From 142e1fc9eae98667c54e07325196d113ecc94c74 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Fri, 20 Jun 2014 09:44:06 +0000 Subject: [PATCH] [OPENMP] Initial support for 'ordered' clause. llvm-svn: 211347 --- clang/include/clang/AST/DataRecursiveASTVisitor.h | 6 ++++ clang/include/clang/AST/OpenMPClause.h | 29 +++++++++++++++++ clang/include/clang/AST/RecursiveASTVisitor.h | 6 ++++ clang/include/clang/Basic/OpenMPKinds.def | 2 ++ clang/include/clang/Parse/Parser.h | 5 +++ clang/include/clang/Sema/Sema.h | 6 ++++ clang/lib/AST/StmtPrinter.cpp | 4 +++ clang/lib/AST/StmtProfile.cpp | 2 ++ clang/lib/Basic/OpenMPKinds.cpp | 2 ++ clang/lib/Parse/ParseOpenMP.cpp | 23 +++++++++++++ clang/lib/Sema/SemaOpenMP.cpp | 39 +++++++++++++++++++++++ clang/lib/Sema/TreeTransform.h | 7 ++++ clang/lib/Serialization/ASTReaderStmt.cpp | 5 +++ clang/lib/Serialization/ASTWriterStmt.cpp | 2 ++ clang/test/OpenMP/for_ast_print.cpp | 8 ++--- clang/tools/libclang/CIndex.cpp | 2 ++ 16 files changed, 144 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/DataRecursiveASTVisitor.h b/clang/include/clang/AST/DataRecursiveASTVisitor.h index e83d726..c0d07f0 100644 --- a/clang/include/clang/AST/DataRecursiveASTVisitor.h +++ b/clang/include/clang/AST/DataRecursiveASTVisitor.h @@ -2351,6 +2351,12 @@ RecursiveASTVisitor::VisitOMPScheduleClause(OMPScheduleClause *C) { } template +bool +RecursiveASTVisitor::VisitOMPOrderedClause(OMPOrderedClause *) { + return true; +} + +template template void RecursiveASTVisitor::VisitOMPClauseList(T *Node) { for (auto *I : Node->varlists()) diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 9df30a3..a46c44a 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -600,6 +600,35 @@ public: StmtRange children() { return StmtRange(&ChunkSize, &ChunkSize + 1); } }; +/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp for ordered +/// \endcode +/// In this example directive '#pragma omp for' has 'ordered' clause. +/// +class OMPOrderedClause : public OMPClause { +public: + /// \brief Build 'ordered' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(OMPC_ordered, StartLoc, EndLoc) {} + + /// \brief Build an empty clause. + /// + OMPOrderedClause() + : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {} + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_ordered; + } + + StmtRange children() { return StmtRange(); } +}; + /// \brief This represents clause 'private' in the '#pragma omp ...' directives. /// /// \code diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 26841d3..c914d37 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2372,6 +2372,12 @@ RecursiveASTVisitor::VisitOMPScheduleClause(OMPScheduleClause *C) { } template +bool +RecursiveASTVisitor::VisitOMPOrderedClause(OMPOrderedClause *) { + return true; +} + +template template void RecursiveASTVisitor::VisitOMPClauseList(T *Node) { for (auto *I : Node->varlists()) diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index f899570..5deff11 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -60,6 +60,7 @@ OPENMP_CLAUSE(aligned, OMPAlignedClause) OPENMP_CLAUSE(copyin, OMPCopyinClause) OPENMP_CLAUSE(proc_bind, OMPProcBindClause) OPENMP_CLAUSE(schedule, OMPScheduleClause) +OPENMP_CLAUSE(ordered, OMPOrderedClause) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) @@ -87,6 +88,7 @@ OPENMP_FOR_CLAUSE(firstprivate) OPENMP_FOR_CLAUSE(reduction) OPENMP_FOR_CLAUSE(collapse) OPENMP_FOR_CLAUSE(schedule) +OPENMP_FOR_CLAUSE(ordered) // Static attributes for 'default' clause. OPENMP_DEFAULT_KIND(none) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index ef09e7a..586545e 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -2351,6 +2351,11 @@ private: /// \param Kind Kind of current clause. /// OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind); + /// \brief Parses clause without any additional arguments. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind); /// \brief Parses clause with the list of variables of a kind \a Kind. /// /// \param Kind Kind of current clause. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 2f5cbef..0795789 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7381,6 +7381,12 @@ public: SourceLocation CommaLoc, SourceLocation EndLoc); + OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'ordered' clause. + OMPClause *ActOnOpenMPOrderedClause(SourceLocation StartLoc, + SourceLocation EndLoc); + OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef Vars, Expr *TailExpr, SourceLocation StartLoc, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index ca18e70..b5c122c 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -638,6 +638,10 @@ void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) { OS << ")"; } +void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *) { + OS << "ordered"; +} + template void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { for (typename T::varlist_iterator I = Node->varlist_begin(), diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index bb41489..534d6bb 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -293,6 +293,8 @@ void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) { Profiler->VisitStmt(C->getChunkSize()); } +void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *) {} + template void OMPClauseProfiler::VisitOMPClauseList(T *Node) { for (auto *I : Node->varlists()) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 131d40a..ec5198e 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -95,6 +95,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_linear: case OMPC_aligned: case OMPC_copyin: + case OMPC_ordered: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -147,6 +148,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_linear: case OMPC_aligned: case OMPC_copyin: + case OMPC_ordered: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 9cd9d4d..599dda4 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -317,6 +317,16 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, Clause = ParseOpenMPSingleExprWithArgClause(CKind); break; + case OMPC_ordered: + // OpenMP [2.7.1, Restrictions, p. 9] + // Only one ordered clause can appear on a loop directive. + if (!FirstClause) { + Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind) + << getOpenMPClauseName(CKind); + } + + Clause = ParseOpenMPClause(CKind); + break; case OMPC_private: case OMPC_firstprivate: case OMPC_lastprivate: @@ -409,6 +419,19 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) { Tok.getLocation()); } +/// \brief Parsing of OpenMP clauses like 'ordered'. +/// +/// ordered-clause: +/// 'ordered' +/// +OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) { + SourceLocation Loc = Tok.getLocation(); + ConsumeAnyToken(); + + return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation()); +} + + /// \brief Parsing of OpenMP clauses with single expressions and some additional /// argument like 'schedule' or 'dist_schedule'. /// diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 515bd5f..23c00381 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1522,6 +1522,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_linear: case OMPC_aligned: case OMPC_copyin: + case OMPC_ordered: case OMPC_threadprivate: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); @@ -1699,6 +1700,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_linear: case OMPC_aligned: case OMPC_copyin: + case OMPC_ordered: case OMPC_threadprivate: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); @@ -1807,6 +1809,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_linear: case OMPC_aligned: case OMPC_copyin: + case OMPC_ordered: case OMPC_threadprivate: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); @@ -1870,6 +1873,41 @@ OMPClause *Sema::ActOnOpenMPScheduleClause( EndLoc, Kind, ValExpr); } +OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, + SourceLocation StartLoc, + SourceLocation EndLoc) { + OMPClause *Res = nullptr; + switch (Kind) { + case OMPC_ordered: + Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); + break; + case OMPC_if: + case OMPC_num_threads: + case OMPC_safelen: + case OMPC_collapse: + case OMPC_schedule: + case OMPC_private: + case OMPC_firstprivate: + case OMPC_lastprivate: + case OMPC_shared: + case OMPC_reduction: + case OMPC_linear: + case OMPC_aligned: + case OMPC_copyin: + case OMPC_default: + case OMPC_proc_bind: + case OMPC_threadprivate: + case OMPC_unknown: + llvm_unreachable("Clause is not allowed."); + } + return Res; +} + +OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPOrderedClause(StartLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef VarList, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, @@ -1911,6 +1949,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_default: case OMPC_proc_bind: case OMPC_schedule: + case OMPC_ordered: case OMPC_threadprivate: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 69685a9..27b134c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6500,6 +6500,13 @@ TreeTransform::TransformOMPScheduleClause(OMPScheduleClause *C) { template OMPClause * +TreeTransform::TransformOMPOrderedClause(OMPOrderedClause *C) { + // No need to rebuild this clause, no template-dependent parameters. + return C; +} + +template +OMPClause * TreeTransform::TransformOMPPrivateClause(OMPPrivateClause *C) { llvm::SmallVector Vars; Vars.reserve(C->varlist_size()); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index cda8355..65f8670 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1694,6 +1694,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_schedule: C = new (Context) OMPScheduleClause(); break; + case OMPC_ordered: + C = new (Context) OMPOrderedClause(); + break; case OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]); break; @@ -1769,6 +1772,8 @@ void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) { C->setCommaLoc(Reader->ReadSourceLocation(Record, Idx)); } +void OMPClauseReader::VisitOMPOrderedClause(OMPOrderedClause *) {} + void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) { C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); unsigned NumVars = C->varlist_size(); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 0de9221..3904192 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1715,6 +1715,8 @@ void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) { Writer->Writer.AddSourceLocation(C->getCommaLoc(), Record); } +void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *) {} + void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { Record.push_back(C->varlist_size()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); diff --git a/clang/test/OpenMP/for_ast_print.cpp b/clang/test/OpenMP/for_ast_print.cpp index 665c0c5..96c7fb1 100644 --- a/clang/test/OpenMP/for_ast_print.cpp +++ b/clang/test/OpenMP/for_ast_print.cpp @@ -20,12 +20,12 @@ T tmain(T argc) { // CHECK-NEXT: for (int i = 0; i < 2; ++i) // CHECK-NEXT: a = 2; #pragma omp parallel -#pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) +#pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered for (int i = 0; i < 10; ++i) for (int j = 0; j < 10; ++j) foo(); // CHECK-NEXT: #pragma omp parallel - // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) + // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: for (int j = 0; j < 10; ++j) // CHECK-NEXT: foo(); @@ -43,12 +43,12 @@ int main(int argc, char **argv) { // CHECK-NEXT: for (int i = 0; i < 2; ++i) // CHECK-NEXT: a = 2; #pragma omp parallel -#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) +#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered for (int i = 0; i < 10; ++i) for (int j = 0; j < 10; ++j) foo(); // CHECK-NEXT: #pragma omp parallel - // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) + // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: for (int j = 0; j < 10; ++j) // CHECK-NEXT: foo(); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 0958634..85b20f3 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -1949,6 +1949,8 @@ void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) { Visitor->AddStmt(C->getChunkSize()); } +void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {} + template void OMPClauseEnqueue::VisitOMPClauseList(T *Node) { for (const auto *I : Node->varlists()) -- 2.7.4