diff options
Diffstat (limited to 'include/clang/AST/StmtOpenMP.h')
-rw-r--r-- | include/clang/AST/StmtOpenMP.h | 302 |
1 files changed, 294 insertions, 8 deletions
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index e37f5b1e0004..ddfb3060b158 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -17,6 +17,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/OpenMPClause.h" #include "clang/AST/Stmt.h" +#include "clang/AST/StmtCXX.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/SourceLocation.h" @@ -448,7 +449,8 @@ class OMPLoopDirective : public OMPExecutableDirective { PreInitsOffset = 8, // The '...End' enumerators do not correspond to child expressions - they // specify the offset to the end (and start of the following counters/ - // updates/finals arrays). + // updates/finals/dependent_counters/dependent_inits/finals_conditions + // arrays). DefaultEnd = 9, // The following 8 exprs are used by worksharing and distribute loops only. IsLastIterVariableOffset = 9, @@ -474,7 +476,8 @@ class OMPLoopDirective : public OMPExecutableDirective { CombinedNextUpperBoundOffset = 27, CombinedDistConditionOffset = 28, CombinedParForInDistConditionOffset = 29, - // Offset to the end (and start of the following counters/updates/finals + // Offset to the end (and start of the following + // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions // arrays) for combined distribute loop directives. CombinedDistributeEnd = 30, }; @@ -517,6 +520,30 @@ class OMPLoopDirective : public OMPExecutableDirective { return MutableArrayRef<Expr *>(Storage, CollapsedNum); } + /// Get the dependent counters storage. + MutableArrayRef<Expr *> getDependentCounters() { + Expr **Storage = reinterpret_cast<Expr **>( + &*std::next(child_begin(), + getArraysOffset(getDirectiveKind()) + 5 * CollapsedNum)); + return MutableArrayRef<Expr *>(Storage, CollapsedNum); + } + + /// Get the dependent inits storage. + MutableArrayRef<Expr *> getDependentInits() { + Expr **Storage = reinterpret_cast<Expr **>( + &*std::next(child_begin(), + getArraysOffset(getDirectiveKind()) + 6 * CollapsedNum)); + return MutableArrayRef<Expr *>(Storage, CollapsedNum); + } + + /// Get the finals conditions storage. + MutableArrayRef<Expr *> getFinalsConditions() { + Expr **Storage = reinterpret_cast<Expr **>( + &*std::next(child_begin(), + getArraysOffset(getDirectiveKind()) + 7 * CollapsedNum)); + return MutableArrayRef<Expr *>(Storage, CollapsedNum); + } + protected: /// Build instance of loop directive of class \a Kind. /// @@ -551,9 +578,10 @@ protected: /// Children number. static unsigned numLoopChildren(unsigned CollapsedNum, OpenMPDirectiveKind Kind) { - return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters, - // PrivateCounters, Inits, - // Updates and Finals + return getArraysOffset(Kind) + + 8 * CollapsedNum; // Counters, PrivateCounters, Inits, + // Updates, Finals, DependentCounters, + // DependentInits, FinalsConditions. } void setIterationVariable(Expr *IV) { @@ -703,6 +731,9 @@ protected: void setInits(ArrayRef<Expr *> A); void setUpdates(ArrayRef<Expr *> A); void setFinals(ArrayRef<Expr *> A); + void setDependentCounters(ArrayRef<Expr *> A); + void setDependentInits(ArrayRef<Expr *> A); + void setFinalsConditions(ArrayRef<Expr *> A); public: /// The expressions built to support OpenMP loops in combined/composite @@ -798,6 +829,15 @@ public: SmallVector<Expr *, 4> Updates; /// Final loop counter values for GodeGen. SmallVector<Expr *, 4> Finals; + /// List of counters required for the generation of the non-rectangular + /// loops. + SmallVector<Expr *, 4> DependentCounters; + /// List of initializers required for the generation of the non-rectangular + /// loops. + SmallVector<Expr *, 4> DependentInits; + /// List of final conditions required for the generation of the + /// non-rectangular loops. + SmallVector<Expr *, 4> FinalsConditions; /// Init statement for all captured expressions. Stmt *PreInits; @@ -813,7 +853,9 @@ public: } /// Initialize all the fields to null. - /// \param Size Number of elements in the counters/finals/updates arrays. + /// \param Size Number of elements in the + /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions + /// arrays. void clear(unsigned Size) { IterationVarRef = nullptr; LastIteration = nullptr; @@ -839,12 +881,18 @@ public: Inits.resize(Size); Updates.resize(Size); Finals.resize(Size); + DependentCounters.resize(Size); + DependentInits.resize(Size); + FinalsConditions.resize(Size); for (unsigned i = 0; i < Size; ++i) { Counters[i] = nullptr; PrivateCounters[i] = nullptr; Inits[i] = nullptr; Updates[i] = nullptr; Finals[i] = nullptr; + DependentCounters[i] = nullptr; + DependentInits[i] = nullptr; + FinalsConditions[i] = nullptr; } PreInits = nullptr; DistCombinedFields.LB = nullptr; @@ -1040,10 +1088,22 @@ public: // This relies on the loop form is already checked by Sema. const Stmt *Body = getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers(); - Body = cast<ForStmt>(Body)->getBody(); + if (auto *For = dyn_cast<ForStmt>(Body)) { + Body = For->getBody(); + } else { + assert(isa<CXXForRangeStmt>(Body) && + "Expected canonical for loop or range-based for loop."); + Body = cast<CXXForRangeStmt>(Body)->getBody(); + } for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) { Body = Body->IgnoreContainers(); - Body = cast<ForStmt>(Body)->getBody(); + if (auto *For = dyn_cast<ForStmt>(Body)) { + Body = For->getBody(); + } else { + assert(isa<CXXForRangeStmt>(Body) && + "Expected canonical for loop or range-based for loop."); + Body = cast<CXXForRangeStmt>(Body)->getBody(); + } } return Body; } @@ -1078,6 +1138,24 @@ public: return const_cast<OMPLoopDirective *>(this)->getFinals(); } + ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } + + ArrayRef<Expr *> dependent_counters() const { + return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); + } + + ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } + + ArrayRef<Expr *> dependent_inits() const { + return const_cast<OMPLoopDirective *>(this)->getDependentInits(); + } + + ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } + + ArrayRef<Expr *> finals_conditions() const { + return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPSimdDirectiveClass || T->getStmtClass() == OMPForDirectiveClass || @@ -1086,6 +1164,9 @@ public: T->getStmtClass() == OMPParallelForSimdDirectiveClass || T->getStmtClass() == OMPTaskLoopDirectiveClass || T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || + T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || + T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || + T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || T->getStmtClass() == OMPDistributeDirectiveClass || T->getStmtClass() == OMPTargetParallelForDirectiveClass || T->getStmtClass() == OMPDistributeParallelForDirectiveClass || @@ -3041,6 +3122,211 @@ public: } }; +/// This represents '#pragma omp master taskloop' directive. +/// +/// \code +/// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) +/// \endcode +/// In this example directive '#pragma omp master taskloop' has clauses +/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' +/// and 'num_tasks' with expression 'num'. +/// +class OMPMasterTaskLoopDirective : public OMPLoopDirective { + friend class ASTStmtReader; + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass, + OMPD_master_taskloop, StartLoc, EndLoc, CollapsedNum, + NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass, + OMPD_master_taskloop, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPMasterTaskLoopDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; + } +}; + +/// This represents '#pragma omp master taskloop simd' directive. +/// +/// \code +/// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) +/// \endcode +/// In this example directive '#pragma omp master taskloop simd' has clauses +/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' +/// and 'num_tasks' with expression 'num'. +/// +class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { + friend class ASTStmtReader; + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPMasterTaskLoopSimdDirectiveClass, + OMPD_master_taskloop_simd, StartLoc, EndLoc, + CollapsedNum, NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPMasterTaskLoopSimdDirectiveClass, + OMPD_master_taskloop_simd, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +public: + /// Creates directive with a list of \p Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPMasterTaskLoopSimdDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place for \p NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; + } +}; + +/// This represents '#pragma omp parallel master taskloop' directive. +/// +/// \code +/// #pragma omp parallel master taskloop private(a,b) grainsize(val) +/// num_tasks(num) +/// \endcode +/// In this example directive '#pragma omp parallel master taskloop' has clauses +/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' +/// and 'num_tasks' with expression 'num'. +/// +class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { + friend class ASTStmtReader; + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, + SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass, + OMPD_parallel_master_taskloop, StartLoc, EndLoc, + CollapsedNum, NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass, + OMPD_parallel_master_taskloop, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPParallelMasterTaskLoopDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; + } +}; + /// This represents '#pragma omp distribute' directive. /// /// \code |