[llvm] 56c1660 - [OpenMP] Initial parsing/sema for 'strict' modifier with 'num_tasks' clause
Mike Rice via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 18 16:27:14 PST 2022
Author: Fazlay Rabbi
Date: 2022-11-18T16:26:47-08:00
New Revision: 56c166017055595a9f26933e85bfd89e30c528d0
URL: https://github.com/llvm/llvm-project/commit/56c166017055595a9f26933e85bfd89e30c528d0
DIFF: https://github.com/llvm/llvm-project/commit/56c166017055595a9f26933e85bfd89e30c528d0.diff
LOG: [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
Added:
Modified:
clang/include/clang/AST/OpenMPClause.h
clang/include/clang/Basic/OpenMPKinds.def
clang/include/clang/Basic/OpenMPKinds.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/OpenMPClause.cpp
clang/lib/Basic/OpenMPKinds.cpp
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp
clang/test/OpenMP/taskloop_strict_modifier_messages.cpp
llvm/include/llvm/Frontend/OpenMP/OMP.td
Removed:
################################################################################
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 1c9f62355e4ee..21d9f740eddf1 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 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit {
/// Return safe iteration space distance.
Expr *getNumTasks() const { return cast_or_null<Expr>(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 339139abe2a49..a084e9686f5ee 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 da13756b93a47..814c245e8b5b4 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 4628ffe606c6a..82d5ae169c7b3 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11685,8 +11685,10 @@ class Sema final {
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 07022a7e1faa9..1bf14806ce836 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 2a46b462cf0f3..81d68a4c1f459 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<unsigned>(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 820dd179610b6..e8b60ce81fcbb 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 <num_tasks modifier> ':'
+ OpenMPNumTasksClauseModifier Modifier =
+ static_cast<OpenMPNumTasksClauseModifier>(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 a67983da2b66e..e150b0d65ad34 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<OpenMPGrainsizeClauseModifier>(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<OpenMPNumTasksClauseModifier>(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 ee633289db3b9..a917007ee82cf 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2064,11 +2064,13 @@ class TreeTransform {
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide
diff erent 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<Derived>::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 <typename Derived>
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 83e539d14d887..7dc935a68c083 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<OpenMPNumTasksClauseModifier>());
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 2567cb3803835..329407a30f5f9 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 3f2494e16588a..84538582108c4 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<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
}
diff --git a/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp b/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp
index e9024a0aa523a..423554fb37d07 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 18a98ba6af749..49faa945b8358 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";
More information about the llvm-commits
mailing list