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 25namespace 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. 142class 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 155private: 156 /// This AST node's children. 157 Stmt *SubStmts[LastSubStmt + 1] = {}; 158 159 OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {} 160 161public: 162 /// Create a new OMPCanonicalLoop. 163 static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt, 164 CapturedStmt *DistanceFunc, 165 CapturedStmt *LoopVarFunc, 166 DeclRefExpr *LoopVarRef) { 167 OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop(); 168 S->setLoopStmt(LoopStmt); 169 S->setDistanceFunc(DistanceFunc); 170 S->setLoopVarFunc(LoopVarFunc); 171 S->setLoopVarRef(LoopVarRef); 172 return S; 173 } 174 175 /// Create an empty OMPCanonicalLoop for deserialization. 176 static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) { 177 return new (Ctx) OMPCanonicalLoop(); 178 } 179 180 static bool classof(const Stmt *S) { 181 return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass; 182 } 183 184 SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); } 185 SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); } 186 187 /// Return this AST node's children. 188 /// @{ 189 child_range children() { 190 return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 191 } 192 const_child_range children() const { 193 return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 194 } 195 /// @} 196 197 /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt). 198 /// @{ 199 Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; } 200 const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; } 201 void setLoopStmt(Stmt *S) { 202 assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) && 203 "Canonical loop must be a for loop (range-based or otherwise)"); 204 SubStmts[LOOP_STMT] = S; 205 } 206 /// @} 207 208 /// The function that computes the number of loop iterations. Can be evaluated 209 /// before entering the loop but after the syntactical loop's init 210 /// statement(s). 211 /// 212 /// Function signature: void(LogicalTy &Result) 213 /// Any values necessary to compute the distance are captures of the closure. 214 /// @{ 215 CapturedStmt *getDistanceFunc() { 216 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 217 } 218 const CapturedStmt *getDistanceFunc() const { 219 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 220 } 221 void setDistanceFunc(CapturedStmt *S) { 222 assert(S && "Expected non-null captured statement"); 223 SubStmts[DISTANCE_FUNC] = S; 224 } 225 /// @} 226 227 /// The function that computes the loop user variable from a logical iteration 228 /// counter. Can be evaluated as first statement in the loop. 229 /// 230 /// Function signature: void(LoopVarTy &Result, LogicalTy Number) 231 /// Any other values required to compute the loop user variable (such as start 232 /// value, step size) are captured by the closure. In particular, the initial 233 /// value of loop iteration variable is captured by value to be unaffected by 234 /// previous iterations. 235 /// @{ 236 CapturedStmt *getLoopVarFunc() { 237 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 238 } 239 const CapturedStmt *getLoopVarFunc() const { 240 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 241 } 242 void setLoopVarFunc(CapturedStmt *S) { 243 assert(S && "Expected non-null captured statement"); 244 SubStmts[LOOPVAR_FUNC] = S; 245 } 246 /// @} 247 248 /// Reference to the loop user variable as accessed in the loop body. 249 /// @{ 250 DeclRefExpr *getLoopVarRef() { 251 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 252 } 253 const DeclRefExpr *getLoopVarRef() const { 254 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 255 } 256 void setLoopVarRef(DeclRefExpr *E) { 257 assert(E && "Expected non-null loop variable"); 258 SubStmts[LOOPVAR_REF] = E; 259 } 260 /// @} 261}; 262 263/// This is a basic class for representing single OpenMP executable 264/// directive. 265/// 266class OMPExecutableDirective : public Stmt { 267 friend class ASTStmtReader; 268 friend class ASTStmtWriter; 269 270 /// Kind of the directive. 271 OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; 272 /// Starting location of the directive (directive keyword). 273 SourceLocation StartLoc; 274 /// Ending location of the directive. 275 SourceLocation EndLoc; 276 277 /// Get the clauses storage. 278 MutableArrayRef<OMPClause *> getClauses() { 279 if (!Data) 280 return 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 293protected: 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 /// 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> 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> 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 357 void setMappedDirective(OpenMPDirectiveKind MappedDirective) { 358 PrevMappedDirective = MappedDirective; 359 } 360 361public: 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 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: 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> 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 433 void SkipToNextClause() { 434 while (this->I != End && !isa<SpecificClause>(*this->I)) 435 ++this->I; 436 } 437 438 public: 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>> 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>> 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> 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> 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> 496 bool hasClausesOfKind() const { 497 auto Clauses = getClausesOfKind<SpecificClause>(); 498 return Clauses.begin() != Clauses.end(); 499 } 500 501 /// Returns starting location of directive kind. 502 SourceLocation getBeginLoc() const { return StartLoc; } 503 /// Returns ending location of directive. 504 SourceLocation getEndLoc() const { return EndLoc; } 505 506 /// Set starting location of directive kind. 507 /// 508 /// \param Loc New starting location of directive. 509 /// 510 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 511 /// Set ending location of directive. 512 /// 513 /// \param Loc New ending location of directive. 514 /// 515 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 516 517 /// Get number of clauses. 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 /// 528 OMPClause *getClause(unsigned I) const { return clauses()[I]; } 529 530 /// Returns true if directive has associated statement. 531 bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); } 532 533 /// Returns statement associated with the directive. 534 const Stmt *getAssociatedStmt() const { 535 return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt(); 536 } 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. 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. 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 564 const CapturedStmt *getInnermostCapturedStmt() const { 565 return const_cast<OMPExecutableDirective *>(this) 566 ->getInnermostCapturedStmt(); 567 } 568 569 OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 570 571 static bool classof(const Stmt *S) { 572 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 573 S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 574 } 575 576 child_range children() { 577 if (!Data) 578 return child_range(child_iterator(), child_iterator()); 579 return Data->getAssociatedStmtAsRange(); 580 } 581 582 const_child_range children() const { 583 return const_cast<OMPExecutableDirective *>(this)->children(); 584 } 585 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. 601 const Stmt *getStructuredBlock() const { 602 return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock(); 603 } 604 Stmt *getStructuredBlock(); 605 606 const Stmt *getRawStmt() const { 607 return const_cast<OMPExecutableDirective *>(this)->getRawStmt(); 608 } 609 Stmt *getRawStmt() { 610 assert(hasAssociatedStmt() && 611 "Expected directive with the associated statement."); 612 return Data->getRawStmt(); 613 } 614 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/// 627class 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 /// 638 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 639 : OMPExecutableDirective(OMPParallelDirectiveClass, 640 llvm::omp::OMPD_parallel, StartLoc, EndLoc) {} 641 642 /// Build an empty directive. 643 /// 644 explicit OMPParallelDirective() 645 : OMPExecutableDirective(OMPParallelDirectiveClass, 646 llvm::omp::OMPD_parallel, SourceLocation(), 647 SourceLocation()) {} 648 649 /// Sets special task reduction descriptor. 650 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 651 652 /// Set cancel state. 653 void setHasCancel(bool Has) { HasCancel = Has; } 654 655public: 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. 681 Expr *getTaskReductionRefExpr() { 682 return cast_or_null<Expr>(Data->getChildren()[0]); 683 } 684 const Expr *getTaskReductionRefExpr() const { 685 return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr(); 686 } 687 688 /// Return true if current directive has inner cancel directive. 689 bool hasCancel() const { return HasCancel; } 690 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. 698class OMPLoopBasedDirective : public OMPExecutableDirective { 699 friend class ASTStmtReader; 700 701protected: 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 /// 713 OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind, 714 SourceLocation StartLoc, SourceLocation EndLoc, 715 unsigned NumAssociatedLoops) 716 : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc), 717 NumAssociatedLoops(NumAssociatedLoops) {} 718 719public: 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). 830 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. 840 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. 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); 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 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 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 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); 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 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. 975class OMPLoopTransformationDirective : public OMPLoopBasedDirective { 976 friend class ASTStmtReader; 977 978 /// Number of loops generated by this loop transformation. 979 unsigned NumGeneratedLoops = 0; 980 981protected: 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. 990 void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; } 991 992public: 993 /// Return the number of associated (consumed) loops. 994 unsigned getNumAssociatedLoops() const { return getLoopsNumber(); } 995 996 /// Return the number of loops generated by this loop transformation. 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 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/// 1018class 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. 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. 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. 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. 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. 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. 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. 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. 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 1144protected: 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 /// 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. 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. 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 1177 void setIterationVariable(Expr *IV) { 1178 Data->getChildren()[IterationVariableOffset] = IV; 1179 } 1180 void setLastIteration(Expr *LI) { 1181 Data->getChildren()[LastIterationOffset] = LI; 1182 } 1183 void setCalcLastIteration(Expr *CLI) { 1184 Data->getChildren()[CalcLastIterationOffset] = CLI; 1185 } 1186 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; } 1187 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; } 1188 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; } 1189 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; } 1190 void setPreInits(Stmt *PreInits) { 1191 Data->getChildren()[PreInitsOffset] = PreInits; 1192 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 1257 void setPrevLowerBoundVariable(Expr *PrevLB) { 1258 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1259 "expected loop bound sharing directive"); 1260 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB; 1261 } 1262 void setPrevUpperBoundVariable(Expr *PrevUB) { 1263 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1264 "expected loop bound sharing directive"); 1265 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB; 1266 } 1267 void setDistInc(Expr *DistInc) { 1268 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1269 "expected loop bound sharing directive"); 1270 Data->getChildren()[DistIncOffset] = DistInc; 1271 } 1272 void setPrevEnsureUpperBound(Expr *PrevEUB) { 1273 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1274 "expected loop bound sharing directive"); 1275 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB; 1276 } 1277 void setCombinedLowerBoundVariable(Expr *CombLB) { 1278 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1279 "expected loop bound sharing directive"); 1280 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB; 1281 } 1282 void setCombinedUpperBoundVariable(Expr *CombUB) { 1283 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1284 "expected loop bound sharing directive"); 1285 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB; 1286 } 1287 void setCombinedEnsureUpperBound(Expr *CombEUB) { 1288 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1289 "expected loop bound sharing directive"); 1290 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB; 1291 } 1292 void setCombinedInit(Expr *CombInit) { 1293 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1294 "expected loop bound sharing directive"); 1295 Data->getChildren()[CombinedInitOffset] = CombInit; 1296 } 1297 void setCombinedCond(Expr *CombCond) { 1298 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1299 "expected loop bound sharing directive"); 1300 Data->getChildren()[CombinedConditionOffset] = CombCond; 1301 } 1302 void setCombinedNextLowerBound(Expr *CombNLB) { 1303 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1304 "expected loop bound sharing directive"); 1305 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB; 1306 } 1307 void setCombinedNextUpperBound(Expr *CombNUB) { 1308 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1309 "expected loop bound sharing directive"); 1310 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB; 1311 } 1312 void setCombinedDistCond(Expr *CombDistCond) { 1313 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1314 "expected loop bound distribute sharing directive"); 1315 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond; 1316 } 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 1332public: 1333 Expr *getIterationVariable() const { 1334 return cast<Expr>(Data->getChildren()[IterationVariableOffset]); 1335 } 1336 Expr *getLastIteration() const { 1337 return cast<Expr>(Data->getChildren()[LastIterationOffset]); 1338 } 1339 Expr *getCalcLastIteration() const { 1340 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]); 1341 } 1342 Expr *getPreCond() const { 1343 return cast<Expr>(Data->getChildren()[PreConditionOffset]); 1344 } 1345 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); } 1346 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); } 1347 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); } 1348 const Stmt *getPreInits() const { 1349 return Data->getChildren()[PreInitsOffset]; 1350 } 1351 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 1416 Expr *getPrevLowerBoundVariable() const { 1417 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1418 "expected loop bound sharing directive"); 1419 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]); 1420 } 1421 Expr *getPrevUpperBoundVariable() const { 1422 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1423 "expected loop bound sharing directive"); 1424 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]); 1425 } 1426 Expr *getDistInc() const { 1427 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1428 "expected loop bound sharing directive"); 1429 return cast<Expr>(Data->getChildren()[DistIncOffset]); 1430 } 1431 Expr *getPrevEnsureUpperBound() const { 1432 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1433 "expected loop bound sharing directive"); 1434 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]); 1435 } 1436 Expr *getCombinedLowerBoundVariable() const { 1437 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1438 "expected loop bound sharing directive"); 1439 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]); 1440 } 1441 Expr *getCombinedUpperBoundVariable() const { 1442 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1443 "expected loop bound sharing directive"); 1444 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]); 1445 } 1446 Expr *getCombinedEnsureUpperBound() const { 1447 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1448 "expected loop bound sharing directive"); 1449 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]); 1450 } 1451 Expr *getCombinedInit() const { 1452 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1453 "expected loop bound sharing directive"); 1454 return cast<Expr>(Data->getChildren()[CombinedInitOffset]); 1455 } 1456 Expr *getCombinedCond() const { 1457 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1458 "expected loop bound sharing directive"); 1459 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]); 1460 } 1461 Expr *getCombinedNextLowerBound() const { 1462 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1463 "expected loop bound sharing directive"); 1464 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]); 1465 } 1466 Expr *getCombinedNextUpperBound() const { 1467 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1468 "expected loop bound sharing directive"); 1469 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]); 1470 } 1471 Expr *getCombinedDistCond() const { 1472 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1473 "expected loop bound distribute sharing directive"); 1474 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]); 1475 } 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(); 1482 const Stmt *getBody() const { 1483 return const_cast<OMPLoopDirective *>(this)->getBody(); 1484 } 1485 1486 ArrayRef<Expr *> counters() { return getCounters(); } 1487 1488 ArrayRef<Expr *> counters() const { 1489 return const_cast<OMPLoopDirective *>(this)->getCounters(); 1490 } 1491 1492 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 1493 1494 ArrayRef<Expr *> private_counters() const { 1495 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 1496 } 1497 1498 ArrayRef<Expr *> inits() { return getInits(); } 1499 1500 ArrayRef<Expr *> inits() const { 1501 return const_cast<OMPLoopDirective *>(this)->getInits(); 1502 } 1503 1504 ArrayRef<Expr *> updates() { return getUpdates(); } 1505 1506 ArrayRef<Expr *> updates() const { 1507 return const_cast<OMPLoopDirective *>(this)->getUpdates(); 1508 } 1509 1510 ArrayRef<Expr *> finals() { return getFinals(); } 1511 1512 ArrayRef<Expr *> finals() const { 1513 return const_cast<OMPLoopDirective *>(this)->getFinals(); 1514 } 1515 1516 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } 1517 1518 ArrayRef<Expr *> dependent_counters() const { 1519 return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); 1520 } 1521 1522 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } 1523 1524 ArrayRef<Expr *> dependent_inits() const { 1525 return const_cast<OMPLoopDirective *>(this)->getDependentInits(); 1526 } 1527 1528 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } 1529 1530 ArrayRef<Expr *> finals_conditions() const { 1531 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); 1532 } 1533 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/// 1585class 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 /// 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 /// 1603 explicit OMPSimdDirective(unsigned CollapsedNum) 1604 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, 1605 SourceLocation(), SourceLocation(), CollapsedNum) {} 1606 1607public: 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 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/// 1649class 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 /// 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 /// 1670 explicit OMPForDirective(unsigned CollapsedNum) 1671 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, 1672 SourceLocation(), SourceLocation(), CollapsedNum) {} 1673 1674 /// Sets special task reduction descriptor. 1675 void setTaskReductionRefExpr(Expr *E) { 1676 Data->getChildren()[numLoopChildren(getLoopsNumber(), 1677 llvm::omp::OMPD_for)] = E; 1678 } 1679 1680 /// Set cancel state. 1681 void setHasCancel(bool Has) { HasCancel = Has; } 1682 1683public: 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. 1715 Expr *getTaskReductionRefExpr() { 1716 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 1717 getLoopsNumber(), llvm::omp::OMPD_for)]); 1718 } 1719 const Expr *getTaskReductionRefExpr() const { 1720 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr(); 1721 } 1722 1723 /// Return true if current directive has inner cancel directive. 1724 bool hasCancel() const { return HasCancel; } 1725 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/// 1740class 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 /// 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 /// 1758 explicit OMPForSimdDirective(unsigned CollapsedNum) 1759 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1760 SourceLocation(), SourceLocation(), CollapsedNum) {} 1761 1762public: 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 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/// 1803class 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 /// 1815 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1816 : OMPExecutableDirective(OMPSectionsDirectiveClass, 1817 llvm::omp::OMPD_sections, StartLoc, EndLoc) {} 1818 1819 /// Build an empty directive. 1820 /// 1821 explicit OMPSectionsDirective() 1822 : OMPExecutableDirective(OMPSectionsDirectiveClass, 1823 llvm::omp::OMPD_sections, SourceLocation(), 1824 SourceLocation()) {} 1825 1826 /// Sets special task reduction descriptor. 1827 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 1828 1829 /// Set cancel state. 1830 void setHasCancel(bool Has) { HasCancel = Has; } 1831 1832public: 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. 1859 Expr *getTaskReductionRefExpr() { 1860 return cast_or_null<Expr>(Data->getChildren()[0]); 1861 } 1862 const Expr *getTaskReductionRefExpr() const { 1863 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr(); 1864 } 1865 1866 /// Return true if current directive has inner cancel directive. 1867 bool hasCancel() const { return HasCancel; } 1868 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/// 1880class 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 /// 1892 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1893 : OMPExecutableDirective(OMPSectionDirectiveClass, 1894 llvm::omp::OMPD_section, StartLoc, EndLoc) {} 1895 1896 /// Build an empty directive. 1897 /// 1898 explicit OMPSectionDirective() 1899 : OMPExecutableDirective(OMPSectionDirectiveClass, 1900 llvm::omp::OMPD_section, SourceLocation(), 1901 SourceLocation()) {} 1902 1903public: 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. 1924 void setHasCancel(bool Has) { HasCancel = Has; } 1925 1926 /// Return true if current directive has inner cancel directive. 1927 bool hasCancel() const { return HasCancel; } 1928 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/// 1941class 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 /// 1950 OMPScopeDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1951 : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope, 1952 StartLoc, EndLoc) {} 1953 1954 /// Build an empty directive. 1955 /// 1956 explicit OMPScopeDirective() 1957 : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope, 1958 SourceLocation(), SourceLocation()) {} 1959 1960public: 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 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/// 1993class 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 /// 2001 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2002 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 2003 StartLoc, EndLoc) {} 2004 2005 /// Build an empty directive. 2006 /// 2007 explicit OMPSingleDirective() 2008 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 2009 SourceLocation(), SourceLocation()) {} 2010 2011public: 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 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/// 2044class 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 /// 2052 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2053 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 2054 StartLoc, EndLoc) {} 2055 2056 /// Build an empty directive. 2057 /// 2058 explicit OMPMasterDirective() 2059 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 2060 SourceLocation(), SourceLocation()) {} 2061 2062public: 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 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/// 2092class 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 /// 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 /// 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 /// 2120 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 2121 2122public: 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 /// 2147 DeclarationNameInfo getDirectiveName() const { return DirName; } 2148 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/// 2163class 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 /// 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 /// 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. 2192 void setTaskReductionRefExpr(Expr *E) { 2193 Data->getChildren()[numLoopChildren(getLoopsNumber(), 2194 llvm::omp::OMPD_parallel_for)] = E; 2195 } 2196 2197 /// Set cancel state. 2198 void setHasCancel(bool Has) { HasCancel = Has; } 2199 2200public: 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. 2233 Expr *getTaskReductionRefExpr() { 2234 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 2235 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]); 2236 } 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. 2243 bool hasCancel() const { return HasCancel; } 2244 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/// 2260class 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 /// 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 /// 2279 explicit OMPParallelForSimdDirective(unsigned CollapsedNum) 2280 : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2281 llvm::omp::OMPD_parallel_for_simd, SourceLocation(), 2282 SourceLocation(), CollapsedNum) {} 2283 2284public: 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 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/// 2325class OMPParallelMasterDirective : public OMPExecutableDirective { 2326 friend class ASTStmtReader; 2327 friend class OMPExecutableDirective; 2328 2329 OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2330 : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2331 llvm::omp::OMPD_parallel_master, StartLoc, 2332 EndLoc) {} 2333 2334 explicit OMPParallelMasterDirective() 2335 : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2336 llvm::omp::OMPD_parallel_master, 2337 SourceLocation(), SourceLocation()) {} 2338 2339 /// Sets special task reduction descriptor. 2340 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2341 2342public: 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. 2367 Expr *getTaskReductionRefExpr() { 2368 return cast_or_null<Expr>(Data->getChildren()[0]); 2369 } 2370 const Expr *getTaskReductionRefExpr() const { 2371 return const_cast<OMPParallelMasterDirective *>(this) 2372 ->getTaskReductionRefExpr(); 2373 } 2374 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/// 2388class OMPParallelMaskedDirective final : public OMPExecutableDirective { 2389 friend class ASTStmtReader; 2390 friend class OMPExecutableDirective; 2391 2392 OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2393 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 2394 llvm::omp::OMPD_parallel_masked, StartLoc, 2395 EndLoc) {} 2396 2397 explicit OMPParallelMaskedDirective() 2398 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 2399 llvm::omp::OMPD_parallel_masked, 2400 SourceLocation(), SourceLocation()) {} 2401 2402 /// Sets special task reduction descriptor. 2403 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2404 2405public: 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. 2430 Expr *getTaskReductionRefExpr() { 2431 return cast_or_null<Expr>(Data->getChildren()[0]); 2432 } 2433 const Expr *getTaskReductionRefExpr() const { 2434 return const_cast<OMPParallelMaskedDirective *>(this) 2435 ->getTaskReductionRefExpr(); 2436 } 2437 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/// 2452class 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 /// 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 /// 2471 explicit OMPParallelSectionsDirective() 2472 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2473 llvm::omp::OMPD_parallel_sections, 2474 SourceLocation(), SourceLocation()) {} 2475 2476 /// Sets special task reduction descriptor. 2477 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2478 2479 /// Set cancel state. 2480 void setHasCancel(bool Has) { HasCancel = Has; } 2481 2482public: 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. 2509 Expr *getTaskReductionRefExpr() { 2510 return cast_or_null<Expr>(Data->getChildren()[0]); 2511 } 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. 2518 bool hasCancel() const { return HasCancel; } 2519 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/// 2533class 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 /// 2544 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2545 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2546 StartLoc, EndLoc) {} 2547 2548 /// Build an empty directive. 2549 /// 2550 explicit OMPTaskDirective() 2551 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2552 SourceLocation(), SourceLocation()) {} 2553 2554 /// Set cancel state. 2555 void setHasCancel(bool Has) { HasCancel = Has; } 2556 2557public: 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. 2582 bool hasCancel() const { return HasCancel; } 2583 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/// 2595class 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 /// 2603 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2604 : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2605 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {} 2606 2607 /// Build an empty directive. 2608 /// 2609 explicit OMPTaskyieldDirective() 2610 : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2611 llvm::omp::OMPD_taskyield, SourceLocation(), 2612 SourceLocation()) {} 2613 2614public: 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 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/// 2641class 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 /// 2649 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2650 : OMPExecutableDirective(OMPBarrierDirectiveClass, 2651 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {} 2652 2653 /// Build an empty directive. 2654 /// 2655 explicit OMPBarrierDirective() 2656 : OMPExecutableDirective(OMPBarrierDirectiveClass, 2657 llvm::omp::OMPD_barrier, SourceLocation(), 2658 SourceLocation()) {} 2659 2660public: 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 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/// 2687class 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 /// 2695 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2696 : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2697 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {} 2698 2699 /// Build an empty directive. 2700 /// 2701 explicit OMPTaskwaitDirective() 2702 : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2703 llvm::omp::OMPD_taskwait, SourceLocation(), 2704 SourceLocation()) {} 2705 2706public: 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 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/// 2738class 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 /// 2746 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2747 : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2748 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {} 2749 2750 /// Build an empty directive. 2751 /// 2752 explicit OMPTaskgroupDirective() 2753 : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2754 llvm::omp::OMPD_taskgroup, SourceLocation(), 2755 SourceLocation()) {} 2756 2757 /// Sets the task_reduction return variable. 2758 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; } 2759 2760public: 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. 2785 const Expr *getReductionRef() const { 2786 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef(); 2787 } 2788 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); } 2789 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. 2805class 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 /// 2813 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2814 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2815 StartLoc, EndLoc) {} 2816 2817 /// Build an empty directive. 2818 /// 2819 explicit OMPFlushDirective() 2820 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2821 SourceLocation(), SourceLocation()) {} 2822 2823public: 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 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. 2857class 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 /// 2866 OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2867 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2868 StartLoc, EndLoc) {} 2869 2870 /// Build an empty directive. 2871 /// 2872 explicit OMPDepobjDirective() 2873 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2874 SourceLocation(), SourceLocation()) {} 2875 2876public: 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 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/// 2909class 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 /// 2917 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2918 : OMPExecutableDirective(OMPOrderedDirectiveClass, 2919 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {} 2920 2921 /// Build an empty directive. 2922 /// 2923 explicit OMPOrderedDirective() 2924 : OMPExecutableDirective(OMPOrderedDirectiveClass, 2925 llvm::omp::OMPD_ordered, SourceLocation(), 2926 SourceLocation()) {} 2927 2928public: 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 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/// 2963class 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 /// 2997 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2998 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 2999 StartLoc, EndLoc) {} 3000 3001 /// Build an empty directive. 3002 /// 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. 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)'. 3022 void setUpdateExpr(Expr *UE) { 3023 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE; 3024 } 3025 /// Set 'v' part of the associated expression/statement. 3026 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } 3027 /// Set 'r' part of the associated expression/statement. 3028 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; } 3029 /// Set 'expr' part of the associated expression/statement. 3030 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } 3031 /// Set 'd' part of the associated expression/statement. 3032 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; } 3033 /// Set conditional expression in `atomic compare`. 3034 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; } 3035 3036public: 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. 3089 Expr *getX() { 3090 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 3091 } 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)'. 3098 Expr *getUpdateExpr() { 3099 return cast_or_null<Expr>( 3100 Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 3101 } 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)'. 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'. 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). 3115 bool isFailOnly() const { return Flags.IsFailOnly; } 3116 /// Get 'v' part of the associated expression/statement. 3117 Expr *getV() { 3118 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 3119 } 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. 3124 Expr *getR() { 3125 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 3126 } 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. 3131 Expr *getExpr() { 3132 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 3133 } 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. 3138 Expr *getD() { 3139 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 3140 } 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. 3145 Expr *getCondExpr() { 3146 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 3147 } 3148 Expr *getCondExpr() const { 3149 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 3150 } 3151 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/// 3165class 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 /// 3173 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3174 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3175 StartLoc, EndLoc) {} 3176 3177 /// Build an empty directive. 3178 /// 3179 explicit OMPTargetDirective() 3180 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3181 SourceLocation(), SourceLocation()) {} 3182 3183public: 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 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/// 3219class 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 /// 3227 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3228 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3229 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} 3230 3231 /// Build an empty directive. 3232 /// 3233 explicit OMPTargetDataDirective() 3234 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3235 llvm::omp::OMPD_target_data, SourceLocation(), 3236 SourceLocation()) {} 3237 3238public: 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 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/// 3273class 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 /// 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 /// 3288 explicit OMPTargetEnterDataDirective() 3289 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3290 llvm::omp::OMPD_target_enter_data, 3291 SourceLocation(), SourceLocation()) {} 3292 3293public: 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 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/// 3328class 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 /// 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 /// 3343 explicit OMPTargetExitDataDirective() 3344 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3345 llvm::omp::OMPD_target_exit_data, 3346 SourceLocation(), SourceLocation()) {} 3347 3348public: 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 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/// 3382class 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 /// 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 /// 3400 explicit OMPTargetParallelDirective() 3401 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3402 llvm::omp::OMPD_target_parallel, 3403 SourceLocation(), SourceLocation()) {} 3404 3405 /// Sets special task reduction descriptor. 3406 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 3407 /// Set cancel state. 3408 void setHasCancel(bool Has) { HasCancel = Has; } 3409 3410public: 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. 3437 Expr *getTaskReductionRefExpr() { 3438 return cast_or_null<Expr>(Data->getChildren()[0]); 3439 } 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. 3446 bool hasCancel() const { return HasCancel; } 3447 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/// 3462class 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 /// 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 /// 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. 3491 void setTaskReductionRefExpr(Expr *E) { 3492 Data->getChildren()[numLoopChildren( 3493 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; 3494 } 3495 3496 /// Set cancel state. 3497 void setHasCancel(bool Has) { HasCancel = Has; } 3498 3499public: 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. 3532 Expr *getTaskReductionRefExpr() { 3533 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 3534 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); 3535 } 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. 3542 bool hasCancel() const { return HasCancel; } 3543 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/// 3557class 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 /// 3565 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3566 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3567 StartLoc, EndLoc) {} 3568 3569 /// Build an empty directive. 3570 /// 3571 explicit OMPTeamsDirective() 3572 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3573 SourceLocation(), SourceLocation()) {} 3574 3575public: 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 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. 3610class 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 /// 3620 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3621 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3622 llvm::omp::OMPD_cancellation_point, StartLoc, 3623 EndLoc) {} 3624 3625 /// Build an empty directive. 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. 3633 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3634 3635public: 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. 3654 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3655 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. 3668class 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 /// 3677 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3678 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3679 StartLoc, EndLoc) {} 3680 3681 /// Build an empty directive. 3682 /// 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. 3689 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3690 3691public: 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. 3712 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3713 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/// 3728class 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 /// 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 /// 3749 explicit OMPTaskLoopDirective(unsigned CollapsedNum) 3750 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3751 SourceLocation(), SourceLocation(), CollapsedNum) {} 3752 3753 /// Set cancel state. 3754 void setHasCancel(bool Has) { HasCancel = Has; } 3755 3756public: 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. 3785 bool hasCancel() const { return HasCancel; } 3786 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/// 3801class 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 /// 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 /// 3820 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) 3821 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3822 llvm::omp::OMPD_taskloop_simd, SourceLocation(), 3823 SourceLocation(), CollapsedNum) {} 3824 3825public: 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 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/// 3867class 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 /// 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 /// 3889 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) 3890 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3891 llvm::omp::OMPD_master_taskloop, SourceLocation(), 3892 SourceLocation(), CollapsedNum) {} 3893 3894 /// Set cancel state. 3895 void setHasCancel(bool Has) { HasCancel = Has; } 3896 3897public: 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. 3927 bool hasCancel() const { return HasCancel; } 3928 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/// 3943class 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 /// 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 /// 3965 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum) 3966 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 3967 llvm::omp::OMPD_masked_taskloop, SourceLocation(), 3968 SourceLocation(), CollapsedNum) {} 3969 3970 /// Set cancel state. 3971 void setHasCancel(bool Has) { HasCancel = Has; } 3972 3973public: 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. 4003 bool hasCancel() const { return HasCancel; } 4004 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/// 4019class 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 /// 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 /// 4038 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4039 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 4040 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), 4041 SourceLocation(), CollapsedNum) {} 4042 4043public: 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 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/// 4084class 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 /// 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 /// 4103 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 4104 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 4105 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(), 4106 SourceLocation(), CollapsedNum) {} 4107 4108public: 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 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/// 4150class 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 /// 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 /// 4173 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) 4174 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4175 llvm::omp::OMPD_parallel_master_taskloop, 4176 SourceLocation(), SourceLocation(), CollapsedNum) {} 4177 4178 /// Set cancel state. 4179 void setHasCancel(bool Has) { HasCancel = Has; } 4180 4181public: 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. 4211 bool hasCancel() const { return HasCancel; } 4212 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/// 4228class 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 /// 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 /// 4251 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum) 4252 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 4253 llvm::omp::OMPD_parallel_masked_taskloop, 4254 SourceLocation(), SourceLocation(), CollapsedNum) {} 4255 4256 /// Set cancel state. 4257 void setHasCancel(bool Has) { HasCancel = Has; } 4258 4259public: 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. 4289 bool hasCancel() const { return HasCancel; } 4290 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/// 4306class 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 /// 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 /// 4326 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4327 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4328 llvm::omp::OMPD_parallel_master_taskloop_simd, 4329 SourceLocation(), SourceLocation(), CollapsedNum) {} 4330 4331public: 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 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/// 4373class 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 /// 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 /// 4393 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 4394 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 4395 llvm::omp::OMPD_parallel_masked_taskloop_simd, 4396 SourceLocation(), SourceLocation(), CollapsedNum) {} 4397 4398public: 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 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/// 4438class 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 /// 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 /// 4458 explicit OMPDistributeDirective(unsigned CollapsedNum) 4459 : OMPLoopDirective(OMPDistributeDirectiveClass, 4460 llvm::omp::OMPD_distribute, SourceLocation(), 4461 SourceLocation(), CollapsedNum) {} 4462 4463public: 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 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/// 4505class 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 /// 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 /// 4520 explicit OMPTargetUpdateDirective() 4521 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4522 llvm::omp::OMPD_target_update, SourceLocation(), 4523 SourceLocation()) {} 4524 4525public: 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 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/// 4561class 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 /// 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 /// 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. 4590 void setTaskReductionRefExpr(Expr *E) { 4591 Data->getChildren()[numLoopChildren( 4592 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; 4593 } 4594 4595 /// Set cancel state. 4596 void setHasCancel(bool Has) { HasCancel = Has; } 4597 4598public: 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. 4631 Expr *getTaskReductionRefExpr() { 4632 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 4633 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); 4634 } 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. 4641 bool hasCancel() const { return HasCancel; } 4642 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/// 4657class 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 /// 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 /// 4678 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) 4679 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4680 llvm::omp::OMPD_distribute_parallel_for_simd, 4681 SourceLocation(), SourceLocation(), CollapsedNum) {} 4682 4683public: 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 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/// 4722class 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 /// 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 /// 4742 explicit OMPDistributeSimdDirective(unsigned CollapsedNum) 4743 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4744 llvm::omp::OMPD_distribute_simd, SourceLocation(), 4745 SourceLocation(), CollapsedNum) {} 4746 4747public: 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 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/// 4788class 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 /// 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 /// 4809 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) 4810 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4811 llvm::omp::OMPD_target_parallel_for_simd, 4812 SourceLocation(), SourceLocation(), CollapsedNum) {} 4813 4814public: 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 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/// 4855class 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 /// 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 /// 4875 explicit OMPTargetSimdDirective(unsigned CollapsedNum) 4876 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4877 llvm::omp::OMPD_target_simd, SourceLocation(), 4878 SourceLocation(), CollapsedNum) {} 4879 4880public: 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 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/// 4920class 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 /// 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 /// 4940 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) 4941 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4942 llvm::omp::OMPD_teams_distribute, SourceLocation(), 4943 SourceLocation(), CollapsedNum) {} 4944 4945public: 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 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/// 4986class 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 /// 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 /// 5006 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) 5007 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 5008 llvm::omp::OMPD_teams_distribute_simd, 5009 SourceLocation(), SourceLocation(), CollapsedNum) {} 5010 5011public: 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 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/// 5053class 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 /// 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 /// 5075 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) 5076 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 5077 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5078 SourceLocation(), SourceLocation(), CollapsedNum) {} 5079 5080public: 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 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/// 5120class 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 /// 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 /// 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. 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. 5155 void setHasCancel(bool Has) { HasCancel = Has; } 5156 5157public: 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. 5188 Expr *getTaskReductionRefExpr() { 5189 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5190 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); 5191 } 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. 5198 bool hasCancel() const { return HasCancel; } 5199 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/// 5213class 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 /// 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 /// 5228 explicit OMPTargetTeamsDirective() 5229 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5230 llvm::omp::OMPD_target_teams, SourceLocation(), 5231 SourceLocation()) {} 5232 5233public: 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 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/// 5269class 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 /// 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 /// 5290 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) 5291 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5292 llvm::omp::OMPD_target_teams_distribute, 5293 SourceLocation(), SourceLocation(), CollapsedNum) {} 5294 5295public: 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 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/// 5335class 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 /// 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 /// 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. 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. 5372 void setHasCancel(bool Has) { HasCancel = Has; } 5373 5374public: 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. 5405 Expr *getTaskReductionRefExpr() { 5406 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5407 getLoopsNumber(), 5408 llvm::omp::OMPD_target_teams_distribute_parallel_for)]); 5409 } 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. 5416 bool hasCancel() const { return HasCancel; } 5417 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/// 5433class 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 /// 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 /// 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 5463public: 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 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/// 5504class 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 /// 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 /// 5525 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) 5526 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5527 llvm::omp::OMPD_target_teams_distribute_simd, 5528 SourceLocation(), SourceLocation(), CollapsedNum) {} 5529 5530public: 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 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. 5562class 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 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 5580 void setPreInits(Stmt *PreInits) { 5581 Data->getChildren()[PreInitsOffset] = PreInits; 5582 } 5583 5584 void setTransformedStmt(Stmt *S) { 5585 Data->getChildren()[TransformedStmtOffset] = S; 5586 } 5587 5588public: 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. 5626 Stmt *getTransformedStmt() const { 5627 return Data->getChildren()[TransformedStmtOffset]; 5628 } 5629 5630 /// Return preinits statement. 5631 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5632 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 5644class 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 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. 5660 void setPreInits(Stmt *PreInits) { 5661 Data->getChildren()[PreInitsOffset] = PreInits; 5662 } 5663 5664 /// Set the de-sugared statement. 5665 void setTransformedStmt(Stmt *S) { 5666 Data->getChildren()[TransformedStmtOffset] = S; 5667 } 5668 5669public: 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. 5699 Stmt *getTransformedStmt() const { 5700 return Data->getChildren()[TransformedStmtOffset]; 5701 } 5702 5703 /// Return the pre-init statements. 5704 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5705 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'. 5718class 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 /// 5726 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5727 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5728 StartLoc, EndLoc) {} 5729 5730 /// Build an empty directive. 5731 /// 5732 explicit OMPScanDirective() 5733 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5734 SourceLocation(), SourceLocation()) {} 5735 5736public: 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 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/// 5771class 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 /// 5780 OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5781 : OMPExecutableDirective(OMPInteropDirectiveClass, 5782 llvm::omp::OMPD_interop, StartLoc, EndLoc) {} 5783 5784 /// Build an empty directive. 5785 /// 5786 explicit OMPInteropDirective() 5787 : OMPExecutableDirective(OMPInteropDirectiveClass, 5788 llvm::omp::OMPD_interop, SourceLocation(), 5789 SourceLocation()) {} 5790 5791public: 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 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/// 5824class 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. 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 /// 5839 OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5840 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5841 llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} 5842 5843 /// Build an empty directive. 5844 /// 5845 explicit OMPDispatchDirective() 5846 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5847 llvm::omp::OMPD_dispatch, SourceLocation(), 5848 SourceLocation()) {} 5849 5850public: 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. 5875 SourceLocation getTargetCallLoc() const { return TargetCallLoc; } 5876 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/// 5889class 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 /// 5898 OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5899 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5900 StartLoc, EndLoc) {} 5901 5902 /// Build an empty directive. 5903 /// 5904 explicit OMPMaskedDirective() 5905 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5906 SourceLocation(), SourceLocation()) {} 5907 5908public: 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 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/// 5940class OMPMetaDirective final : public OMPExecutableDirective { 5941 friend class ASTStmtReader; 5942 friend class OMPExecutableDirective; 5943 Stmt *IfStmt; 5944 5945 OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5946 : OMPExecutableDirective(OMPMetaDirectiveClass, 5947 llvm::omp::OMPD_metadirective, StartLoc, 5948 EndLoc) {} 5949 explicit OMPMetaDirective() 5950 : OMPExecutableDirective(OMPMetaDirectiveClass, 5951 llvm::omp::OMPD_metadirective, SourceLocation(), 5952 SourceLocation()) {} 5953 5954 void setIfStmt(Stmt *S) { IfStmt = S; } 5955 5956public: 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); 5963 Stmt *getIfStmt() const { return IfStmt; } 5964 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/// 5979class 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 /// 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 /// 5997 explicit OMPGenericLoopDirective(unsigned CollapsedNum) 5998 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 5999 SourceLocation(), SourceLocation(), CollapsedNum) {} 6000 6001public: 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 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/// 6041class 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 /// 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 /// 6060 explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum) 6061 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 6062 llvm::omp::OMPD_teams_loop, SourceLocation(), 6063 SourceLocation(), CollapsedNum) {} 6064 6065public: 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 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/// 6106class 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 /// 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 /// 6126 explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum) 6127 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 6128 llvm::omp::OMPD_target_teams_loop, SourceLocation(), 6129 SourceLocation(), CollapsedNum) {} 6130 6131public: 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 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/// 6172class 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 /// 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 /// 6191 explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum) 6192 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 6193 llvm::omp::OMPD_parallel_loop, SourceLocation(), 6194 SourceLocation(), CollapsedNum) {} 6195 6196public: 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 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/// 6237class 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 /// 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 /// 6257 explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum) 6258 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 6259 llvm::omp::OMPD_target_parallel_loop, SourceLocation(), 6260 SourceLocation(), CollapsedNum) {} 6261 6262public: 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 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 6299class 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 /// 6307 OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc) 6308 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6309 StartLoc, EndLoc) {} 6310 /// Build an empty directive. 6311 /// 6312 explicit OMPErrorDirective() 6313 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6314 SourceLocation(), SourceLocation()) {} 6315 6316public: 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 6334 static bool classof(const Stmt *T) { 6335 return T->getStmtClass() == OMPErrorDirectiveClass; 6336 } 6337}; 6338} // end namespace clang 6339 6340#endif 6341