From: Fazlay Rabbi Date: Fri, 18 Nov 2022 23:21:49 +0000 (-0800) Subject: [OpenMP] Initial parsing/sema for 'strict' modifier with 'num_tasks' clause X-Git-Tag: upstream/17.0.6~27134 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=56c166017055595a9f26933e85bfd89e30c528d0;p=platform%2Fupstream%2Fllvm.git [OpenMP] Initial parsing/sema for 'strict' modifier with 'num_tasks' clause This patch gives basic parsing and semantic analysis support for 'strict' modifier with 'num_tasks' clause of 'taskloop' construct introduced in OpenMP 5.1 (section 2.12.2) Differential Revision: https://reviews.llvm.org/D138328 --- diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 1c9f623..21d9f74 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -6486,26 +6486,43 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { /// Location of '('. SourceLocation LParenLoc; + /// Modifiers for 'num_tasks' clause. + OpenMPNumTasksClauseModifier Modifier = OMPC_NUMTASKS_unknown; + + /// Location of the modifier. + SourceLocation ModifierLoc; + /// Safe iteration space distance. Stmt *NumTasks = nullptr; /// Set safelen. void setNumTasks(Expr *Size) { NumTasks = Size; } + /// Sets modifier. + void setModifier(OpenMPNumTasksClauseModifier M) { Modifier = M; } + + /// Sets modifier location. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + public: /// Build 'num_tasks' clause. /// + /// \param Modifier Clause modifier. /// \param Size Expression associated with this clause. /// \param HelperSize Helper grainsize for the construct. /// \param CaptureRegion Innermost OpenMP region where expressions in this /// clause must be captured. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - OMPNumTasksClause(Expr *Size, Stmt *HelperSize, - OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc) + /// \param ModifierLoc Modifier location. + /// \param LParenLoc Location of '('. + OMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *Size, + Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), + ModifierLoc(ModifierLoc), NumTasks(Size) { setPreInitStmt(HelperSize, CaptureRegion); } @@ -6524,6 +6541,12 @@ public: /// Return safe iteration space distance. Expr *getNumTasks() const { return cast_or_null(NumTasks); } + /// Gets modifier. + OpenMPNumTasksClauseModifier getModifier() const { return Modifier; } + + /// Gets modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } + child_range children() { return child_range(&NumTasks, &NumTasks + 1); } const_child_range children() const { diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 339139a..a084e96 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -74,6 +74,9 @@ #ifndef OPENMP_GRAINSIZE_MODIFIER #define OPENMP_GRAINSIZE_MODIFIER(Name) #endif +#ifndef OPENMP_NUMTASKS_MODIFIER +#define OPENMP_NUMTASKS_MODIFIER(Name) +#endif // Static attributes for 'schedule' clause. OPENMP_SCHEDULE_KIND(static) @@ -187,6 +190,10 @@ OPENMP_BIND_KIND(thread) // Modifiers for the 'grainsize' clause. OPENMP_GRAINSIZE_MODIFIER(strict) +// Modifiers for the 'num_tasks' clause. +OPENMP_NUMTASKS_MODIFIER(strict) + +#undef OPENMP_NUMTASKS_MODIFIER #undef OPENMP_GRAINSIZE_MODIFIER #undef OPENMP_BIND_KIND #undef OPENMP_ADJUST_ARGS_KIND diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index da13756..814c245 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -201,6 +201,12 @@ enum OpenMPGrainsizeClauseModifier { OMPC_GRAINSIZE_unknown }; +enum OpenMPNumTasksClauseModifier { +#define OPENMP_NUMTASKS_MODIFIER(Name) OMPC_NUMTASKS_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_NUMTASKS_unknown +}; + /// Contains 'interop' data for 'append_args' and 'init' clauses. class Expr; struct OMPInteropInfo final { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4628ffe..82d5ae1 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11685,8 +11685,10 @@ public: SourceLocation ModifierLoc, SourceLocation EndLoc); /// Called on well-formed 'num_tasks' clause. - OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, + OMPClause *ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, + Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc); /// Called on well-formed 'hint' clause. OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 07022a7..1bf1480 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1931,6 +1931,11 @@ void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) { void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) { OS << "num_tasks("; + OpenMPNumTasksClauseModifier Modifier = Node->getModifier(); + if (Modifier != OMPC_NUMTASKS_unknown) { + OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier) + << ": "; + } Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0); OS << ")"; } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 2a46b46..81d68a4 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -158,6 +158,15 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, return OMPC_GRAINSIZE_unknown; return Type; } + case OMPC_num_tasks: { + unsigned Type = llvm::StringSwitch(Str) +#define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_NUMTASKS_unknown); + if (LangOpts.OpenMP < 51) + return OMPC_NUMTASKS_unknown; + return Type; + } case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -198,7 +207,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, case OMPC_thread_limit: case OMPC_priority: case OMPC_nogroup: - case OMPC_num_tasks: case OMPC_hint: case OMPC_uniform: case OMPC_use_device_ptr: @@ -454,6 +462,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier"); + case OMPC_num_tasks: + switch (Type) { + case OMPC_NUMTASKS_unknown: + return "unknown"; +#define OPENMP_NUMTASKS_MODIFIER(Name) \ + case OMPC_NUMTASKS_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -494,7 +512,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_thread_limit: case OMPC_priority: case OMPC_nogroup: - case OMPC_num_tasks: case OMPC_hint: case OMPC_uniform: case OMPC_use_device_ptr: diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 820dd17..e8b60ce 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3226,7 +3226,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, if ((CKind == OMPC_ordered || CKind == OMPC_partial) && PP.LookAhead(/*N=*/0).isNot(tok::l_paren)) Clause = ParseOpenMPClause(CKind, WrongDirective); - else if (CKind == OMPC_grainsize) + else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks) Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective); else Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective); @@ -3900,6 +3900,33 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, Arg.push_back(OMPC_GRAINSIZE_unknown); KLoc.emplace_back(); } + } else if (Kind == OMPC_num_tasks) { + // Parse optional ':' + OpenMPNumTasksClauseModifier Modifier = + static_cast(getOpenMPSimpleClauseType( + Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), + getLangOpts())); + if (getLangOpts().OpenMP >= 51) { + if (NextToken().is(tok::colon)) { + Arg.push_back(Modifier); + KLoc.push_back(Tok.getLocation()); + // Parse modifier + ConsumeAnyToken(); + // Parse ':' + ConsumeAnyToken(); + } else { + if (Modifier == OMPC_NUMTASKS_strict) { + Diag(Tok, diag::err_modifier_expected_colon) << "strict"; + // Parse modifier + ConsumeAnyToken(); + } + Arg.push_back(OMPC_NUMTASKS_unknown); + KLoc.emplace_back(); + } + } else { + Arg.push_back(OMPC_NUMTASKS_unknown); + KLoc.emplace_back(); + } } else { assert(Kind == OMPC_if); KLoc.push_back(Tok.getLocation()); @@ -3923,7 +3950,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) || (Kind == OMPC_dist_schedule && DelimLoc.isValid()) || Kind == OMPC_if || Kind == OMPC_device || - Kind == OMPC_grainsize; + Kind == OMPC_grainsize || Kind == OMPC_num_tasks; if (NeedAnExpression) { SourceLocation ELoc = Tok.getLocation(); ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast)); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index a67983d..e150b0d 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -15110,9 +15110,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_priority: Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); break; - case OMPC_num_tasks: - Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); - break; case OMPC_hint: Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); break; @@ -15138,6 +15135,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); break; case OMPC_grainsize: + case OMPC_num_tasks: case OMPC_device: case OMPC_if: case OMPC_default: @@ -16884,6 +16882,13 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( static_cast(Argument.back()), Expr, StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); break; + case OMPC_num_tasks: + assert(Argument.size() == 1 && ArgumentLoc.size() == 1 && + "Modifier for num_tasks clause and its location are expected."); + Res = ActOnOpenMPNumTasksClause( + static_cast(Argument.back()), Expr, + StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); + break; case OMPC_final: case OMPC_num_threads: case OMPC_safelen: @@ -16930,7 +16935,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_thread_limit: case OMPC_priority: case OMPC_nogroup: - case OMPC_num_tasks: case OMPC_hint: case OMPC_unknown: case OMPC_uniform: @@ -22393,10 +22397,21 @@ OMPClause *Sema::ActOnOpenMPGrainsizeClause( StartLoc, LParenLoc, ModifierLoc, EndLoc); } -OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { +OMPClause *Sema::ActOnOpenMPNumTasksClause( + OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) { + assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && + "Unexpected num_tasks modifier in OpenMP < 51."); + + if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) { + std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0, + OMPC_NUMTASKS_unknown); + Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) + << Values << getOpenMPClauseName(OMPC_num_tasks); + return nullptr; + } + Expr *ValExpr = NumTasks; Stmt *HelperValStmt = nullptr; OpenMPDirectiveKind CaptureRegion = OMPD_unknown; @@ -22410,8 +22425,9 @@ OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) return nullptr; - return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, - StartLoc, LParenLoc, EndLoc); + return new (Context) + OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, + StartLoc, LParenLoc, ModifierLoc, EndLoc); } OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index ee63328..a917007 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2064,11 +2064,13 @@ public: /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, + OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, + Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPNumTasksClause(NumTasks, StartLoc, LParenLoc, - EndLoc); + return getSema().ActOnOpenMPNumTasksClause(Modifier, NumTasks, StartLoc, + LParenLoc, ModifierLoc, EndLoc); } /// Build a new OpenMP 'hint' clause. @@ -10363,7 +10365,8 @@ TreeTransform::TransformOMPNumTasksClause(OMPNumTasksClause *C) { if (E.isInvalid()) return nullptr; return getDerived().RebuildOMPNumTasksClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); + C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(), + C->getModifierLoc(), C->getEndLoc()); } template diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 83e539d..7dc935a 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -10792,7 +10792,9 @@ void OMPClauseReader::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { void OMPClauseReader::VisitOMPNumTasksClause(OMPNumTasksClause *C) { VisitOMPClauseWithPreInit(C); + C->setModifier(Record.readEnum()); C->setNumTasks(Record.readSubExpr()); + C->setModifierLoc(Record.readSourceLocation()); C->setLParenLoc(Record.readSourceLocation()); } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 2567cb3..329407a 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6798,7 +6798,9 @@ void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) { VisitOMPClauseWithPreInit(C); + Record.writeEnum(C->getModifier()); Record.AddStmt(C->getNumTasks()); + Record.AddSourceLocation(C->getModifierLoc()); Record.AddSourceLocation(C->getLParenLoc()); } diff --git a/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp b/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp index 3f2494e..8453858 100644 --- a/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp +++ b/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp @@ -56,6 +56,46 @@ T tmain(T argc) { // CHECK-NEXT: #pragma omp cancel taskgroup // CHECK-NEXT: #pragma omp cancellation point taskgroup // CHECK-NEXT: foo(); + +#pragma omp taskgroup +#pragma omp taskloop num_tasks(strict: N) + // CHECK: #pragma omp taskgroup + // CHECK-NEXT: #pragma omp taskloop num_tasks(strict: N) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp parallel +#pragma omp taskloop num_tasks(strict: N) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) { +#pragma omp cancel taskgroup +#pragma omp cancellation point taskgroup + foo(); + } + // CHECK-NEXT: #pragma omp parallel + // CHECK-NEXT: #pragma omp taskloop num_tasks(strict: N) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) { + // CHECK-NEXT: #pragma omp cancel taskgroup + // CHECK-NEXT: #pragma omp cancellation point taskgroup + // CHECK-NEXT: foo(); return T(); } @@ -136,6 +176,77 @@ int main(int argc, char **argv) { // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); +#pragma omp taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp masked taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp masked taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp masked taskloop simd num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp masked taskloop simd num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel masked taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel masked taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel masked taskloop simd num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel masked taskloop simd num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp master taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp master taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp master taskloop simd num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp master taskloop simd num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel master taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel master taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel master taskloop simd num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel master taskloop simd num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + return (tmain(argc) + tmain(argv[0][0])); } diff --git a/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp b/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp index e9024a0..423554f 100644 --- a/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp +++ b/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -ferror-limit 150 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -ferror-limit 150 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -fopenmp-simd -ferror-limit 150 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -fopenmp-simd -ferror-limit 150 %s -Wuninitialized void foo() { } @@ -23,7 +23,15 @@ int tmain(T argc, S **argv) { #pragma omp taskloop grainsize(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'grainsize'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} for (int i = 0; i < 10; ++i) foo(); - + #pragma omp taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); return 0; } @@ -108,6 +116,83 @@ int main(int argc, char **argv) { #pragma omp parallel master taskloop simd grainsize(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'grainsize'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} for (int i = 0; i < 10; ++i) foo(); - + #pragma omp masked taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp masked taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp masked taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp masked taskloop simd num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp masked taskloop simd num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp masked taskloop simd num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp parallel masked taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel masked taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel masked taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp parallel masked taskloop simd num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel masked taskloop simd num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel masked taskloop simd num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp master taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp master taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp master taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp master taskloop simd num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp master taskloop simd num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp master taskloop simd num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp parallel master taskloop simd num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop simd num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop simd num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); return tmain(argc, argv); } diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 18a98ba..49faa94 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -246,9 +246,18 @@ def OMPC_GrainSize : Clause<"grainsize"> { def OMPC_NoGroup : Clause<"nogroup"> { let clangClass = "OMPNogroupClause"; } + +def OMP_NUMTASKS_Strict : ClauseVal<"strict", 1, 1> {} +def OMP_NUMTASKS_Unknown : ClauseVal<"unkonwn", 2, 0> { let isDefault = 1; } + def OMPC_NumTasks : Clause<"num_tasks"> { let clangClass = "OMPNumTasksClause"; let flangClass = "ScalarIntExpr"; + let enumClauseValue = "NumTasksType"; + let allowedClauseValues = [ + OMP_NUMTASKS_Strict, + OMP_NUMTASKS_Unknown + ]; } def OMPC_Hint : Clause<"hint"> { let clangClass = "OMPHintClause";