diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2015-09-25 10:37:12 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-09-25 10:37:12 +0000 |
| commit | 346265e3bcee55bff42849683ec01506e67fc5c8 (patch) | |
| tree | a85101f4317cdc897ec25b43aa6b46b6da817f7a /clang/lib | |
| parent | c2bb0cbe00b66465a4d73886ce7162243d902769 (diff) | |
| download | bcm5719-llvm-346265e3bcee55bff42849683ec01506e67fc5c8.tar.gz bcm5719-llvm-346265e3bcee55bff42849683ec01506e67fc5c8.zip | |
[OPENMP 4.1] Add 'threads' clause for '#pragma omp ordered'.
OpenMP 4.1 extends format of '#pragma omp ordered'. It adds 3 additional clauses: 'threads', 'simd' and 'depend'.
If no clause is specified, the ordered construct behaves as if the threads clause had been specified. If the threads clause is specified, the threads in the team executing the loop region execute ordered regions sequentially in the order of the loop iterations.
The loop region to which an ordered region without any clause or with a threads clause binds must have an ordered clause without the parameter specified on the corresponding loop directive.
llvm-svn: 248569
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/Stmt.cpp | 18 | ||||
| -rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Basic/OpenMPKinds.cpp | 13 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 64 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 7 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 3 |
10 files changed, 107 insertions, 23 deletions
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 58996cd6e68..55f1b64c5ac 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -2176,21 +2176,27 @@ OMPFlushDirective *OMPFlushDirective::CreateEmpty(const ASTContext &C, OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective), - llvm::alignOf<Stmt *>()); - void *Mem = C.Allocate(Size + sizeof(Stmt *)); - OMPOrderedDirective *Dir = new (Mem) OMPOrderedDirective(StartLoc, EndLoc); + llvm::alignOf<OMPClause *>()); + void *Mem = + C.Allocate(Size + sizeof(Stmt *) + sizeof(OMPClause *) * Clauses.size()); + OMPOrderedDirective *Dir = + new (Mem) OMPOrderedDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); Dir->setAssociatedStmt(AssociatedStmt); return Dir; } OMPOrderedDirective *OMPOrderedDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell) { unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective), - llvm::alignOf<Stmt *>()); - void *Mem = C.Allocate(Size + sizeof(Stmt *)); - return new (Mem) OMPOrderedDirective(); + llvm::alignOf<OMPClause *>()); + void *Mem = + C.Allocate(Size + sizeof(Stmt *) + sizeof(OMPClause *) * NumClauses); + return new (Mem) OMPOrderedDirective(NumClauses); } OMPAtomicDirective *OMPAtomicDirective::Create( diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 4a29d38d5b8..3ab8acbb1e1 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -697,6 +697,10 @@ void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) { OS << "seq_cst"; } +void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) { + OS << "threads"; +} + void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) { OS << "device("; Node->getDevice()->printPretty(OS, nullptr, Policy, 0); @@ -958,7 +962,7 @@ void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) { } void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) { - Indent() << "#pragma omp ordered"; + Indent() << "#pragma omp ordered "; PrintOMPExecutableDirective(Node); } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index b379745b4af..874aee1ebec 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -333,6 +333,8 @@ void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {} void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {} +void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {} + template<typename T> void OMPClauseProfiler::VisitOMPClauseList(T *Node) { for (auto *E : Node->varlists()) { diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 30ea09a9f59..ea99387cb94 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -128,6 +128,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_capture: case OMPC_seq_cst: case OMPC_device: + case OMPC_threads: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -212,6 +213,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_capture: case OMPC_seq_cst: case OMPC_device: + case OMPC_threads: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -375,6 +377,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_ordered: + switch (CKind) { +#define OPENMP_ORDERED_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_unknown: case OMPD_threadprivate: case OMPD_section: @@ -385,7 +397,6 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, case OMPD_taskwait: case OMPD_taskgroup: case OMPD_cancellation_point: - case OMPD_ordered: break; } return false; diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 51136413e05..341ccaad542 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -2209,6 +2209,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_depend: case OMPC_mergeable: case OMPC_device: + case OMPC_threads: llvm_unreachable("Clause is not allowed in 'omp atomic'."); } } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 6c9c88a49c2..5f32c63cf30 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -394,7 +394,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause | /// mergeable-clause | flush-clause | read-clause | write-clause | /// update-clause | capture-clause | seq_cst-clause | device-clause | -/// simdlen-clause +/// simdlen-clause | threads-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -472,6 +472,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_update: case OMPC_capture: case OMPC_seq_cst: + case OMPC_threads: // OpenMP [2.7.1, Restrictions, p. 9] // Only one ordered clause can appear on a loop directive. // OpenMP [2.7.1, Restrictions, C/C++, p. 4] @@ -601,6 +602,9 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) { /// read-clause: /// 'read' /// +/// threads-clause: +/// 'threads' +/// OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) { SourceLocation Loc = Tok.getLocation(); ConsumeAnyToken(); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 904556cbc63..9045724aa2b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -96,7 +96,10 @@ private: DeclarationNameInfo DirectiveName; Scope *CurScope; SourceLocation ConstructLoc; - bool OrderedRegion; + /// \brief first argument (Expr *) contains optional argument of the + /// 'ordered' clause, the second one is true if the regions has 'ordered' + /// clause, false otherwise. + llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion; bool NowaitRegion; bool CancelRegion; unsigned CollapseNumber; @@ -105,12 +108,12 @@ private: Scope *CurScope, SourceLocation Loc) : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), - ConstructLoc(Loc), OrderedRegion(false), NowaitRegion(false), + ConstructLoc(Loc), OrderedRegion(), NowaitRegion(false), CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {} SharingMapTy() : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), - ConstructLoc(), OrderedRegion(false), NowaitRegion(false), + ConstructLoc(), OrderedRegion(), NowaitRegion(false), CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {} }; @@ -231,16 +234,23 @@ public: } /// \brief Marks current region as ordered (it has an 'ordered' clause). - void setOrderedRegion(bool IsOrdered = true) { - Stack.back().OrderedRegion = IsOrdered; + void setOrderedRegion(bool IsOrdered, Expr *Param) { + Stack.back().OrderedRegion.setInt(IsOrdered); + Stack.back().OrderedRegion.setPointer(Param); } /// \brief Returns true, if parent region is ordered (has associated /// 'ordered' clause), false - otherwise. bool isParentOrderedRegion() const { if (Stack.size() > 2) - return Stack[Stack.size() - 2].OrderedRegion; + return Stack[Stack.size() - 2].OrderedRegion.getInt(); return false; } + /// \brief Returns optional parameter for the ordered region. + Expr *getParentOrderedRegionParam() const { + if (Stack.size() > 2) + return Stack[Stack.size() - 2].OrderedRegion.getPointer(); + return nullptr; + } /// \brief Marks current region as nowait (it has a 'nowait' clause). void setNowaitRegion(bool IsNowait = true) { Stack.back().NowaitRegion = IsNowait; @@ -2220,9 +2230,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); break; case OMPD_ordered: - assert(ClausesWithImplicit.empty() && - "No clauses are allowed for 'omp ordered' directive"); - Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc); + Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, + EndLoc); break; case OMPD_atomic: Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, @@ -4125,7 +4134,8 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); } -StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, +StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { if (!AStmt) @@ -4135,7 +4145,22 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, getCurFunction()->setHasBranchProtectedScope(); - return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt); + OMPThreadsClause *TC = nullptr; + for (auto *C: Clauses) { + if (C->getClauseKind() == OMPC_threads) + TC = cast<OMPThreadsClause>(C); + } + + // TODO: this must happen only if 'threads' clause specified or if no clauses + // is specified. + if (auto *Param = DSAStack->getParentOrderedRegionParam()) { + SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; + Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) << (TC != nullptr); + Diag(Param->getLocStart(), diag::note_omp_ordered_param); + return StmtError(); + } + + return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); } namespace { @@ -4983,6 +5008,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_capture: case OMPC_seq_cst: case OMPC_depend: + case OMPC_threads: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -5181,7 +5207,6 @@ OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc, Expr *NumForLoops) { - DSAStack->setOrderedRegion(); // OpenMP [2.7.1, loop construct, Description] // OpenMP [2.8.1, simd construct, Description] // OpenMP [2.9.6, distribute construct, Description] @@ -5193,7 +5218,9 @@ OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, if (NumForLoopsResult.isInvalid()) return nullptr; NumForLoops = NumForLoopsResult.get(); - } + } else + NumForLoops = nullptr; + DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); return new (Context) OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); } @@ -5242,6 +5269,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_seq_cst: case OMPC_depend: case OMPC_device: + case OMPC_threads: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -5369,6 +5397,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_seq_cst: case OMPC_depend: case OMPC_device: + case OMPC_threads: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -5472,6 +5501,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_seq_cst: Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); break; + case OMPC_threads: + Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); + break; case OMPC_if: case OMPC_final: case OMPC_num_threads: @@ -5541,6 +5573,11 @@ OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, return new (Context) OMPSeqCstClause(StartLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPThreadsClause(StartLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, @@ -5606,6 +5643,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_capture: case OMPC_seq_cst: case OMPC_device: + case OMPC_threads: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 820fe65c6c8..df998a06fb5 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7367,6 +7367,13 @@ TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) { template <typename Derived> OMPClause * +TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) { + // No need to rebuild this clause, no template-dependent parameters. + return C; +} + +template <typename Derived> +OMPClause * TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) { llvm::SmallVector<Expr *, 16> Vars; Vars.reserve(C->varlist_size()); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 98955f63af2..6969823030d 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1777,6 +1777,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_seq_cst: C = new (Context) OMPSeqCstClause(); break; + case OMPC_threads: + C = new (Context) OMPThreadsClause(); + break; case OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]); break; @@ -1899,6 +1902,8 @@ void OMPClauseReader::VisitOMPCaptureClause(OMPCaptureClause *) {} void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {} +void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {} + void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) { C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); unsigned NumVars = C->varlist_size(); @@ -2281,6 +2286,8 @@ void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) { void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) { VisitStmt(D); + // The NumClauses field was read in ReadStmtFromStream. + ++Idx; VisitOMPExecutableDirective(D); } @@ -2921,7 +2928,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case STMT_OMP_ORDERED_DIRECTIVE: - S = OMPOrderedDirective::CreateEmpty(Context, Empty); + S = OMPOrderedDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); break; case STMT_OMP_ATOMIC_DIRECTIVE: diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 92d21389cbb..5c86dc1b4f5 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1810,6 +1810,8 @@ void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {} void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {} +void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {} + void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { Record.push_back(C->varlist_size()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); @@ -2155,6 +2157,7 @@ void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) { void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) { VisitStmt(D); + Record.push_back(D->getNumClauses()); VisitOMPExecutableDirective(D); Code = serialization::STMT_OMP_ORDERED_DIRECTIVE; } |

