[OPENMP 4.5] Parsing/sema for 'num_tasks' clause.
OpenMP 4.5 adds directives 'taskloop' and 'taskloop simd'. These directives support clause 'num_tasks'. Patch adds parsing/semantic analysis for this clause.
llvm-svn: 255008
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 20c3c73c9..c589d0a 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5367,6 +5367,30 @@
CancelRegion);
}
+static bool checkGrainsizeNumTasksClauses(Sema &S,
+ ArrayRef<OMPClause *> Clauses) {
+ OMPClause *PrevClause = nullptr;
+ bool ErrorFound = false;
+ for (auto *C : Clauses) {
+ if (C->getClauseKind() == OMPC_grainsize ||
+ C->getClauseKind() == OMPC_num_tasks) {
+ if (!PrevClause)
+ PrevClause = C;
+ else if (PrevClause->getClauseKind() != C->getClauseKind()) {
+ S.Diag(C->getLocStart(),
+ diag::err_omp_grainsize_num_tasks_mutually_exclusive)
+ << getOpenMPClauseName(C->getClauseKind())
+ << getOpenMPClauseName(PrevClause->getClauseKind());
+ S.Diag(PrevClause->getLocStart(),
+ diag::note_omp_previous_grainsize_num_tasks)
+ << getOpenMPClauseName(PrevClause->getClauseKind());
+ ErrorFound = true;
+ }
+ }
+ }
+ return ErrorFound;
+}
+
StmtResult Sema::ActOnOpenMPTaskLoopDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
@@ -5388,6 +5412,12 @@
assert((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built");
+ // OpenMP, [2.9.2 taskloop Construct, Restrictions]
+ // The grainsize clause and num_tasks clause are mutually exclusive and may
+ // not appear on the same taskloop directive.
+ if (checkGrainsizeNumTasksClauses(*this, Clauses))
+ return StmtError();
+
getCurFunction()->setHasBranchProtectedScope();
return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
NestedLoopCount, Clauses, AStmt, B);
@@ -5414,6 +5444,12 @@
assert((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built");
+ // OpenMP, [2.9.2 taskloop Construct, Restrictions]
+ // The grainsize clause and num_tasks clause are mutually exclusive and may
+ // not appear on the same taskloop directive.
+ if (checkGrainsizeNumTasksClauses(*this, Clauses))
+ return StmtError();
+
getCurFunction()->setHasBranchProtectedScope();
return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
NestedLoopCount, Clauses, AStmt, B);
@@ -5484,6 +5520,9 @@
case OMPC_grainsize:
Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_num_tasks:
+ Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_default:
case OMPC_proc_bind:
@@ -5790,6 +5829,7 @@
case OMPC_priority:
case OMPC_grainsize:
case OMPC_nogroup:
+ case OMPC_num_tasks:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -5925,6 +5965,7 @@
case OMPC_priority:
case OMPC_grainsize:
case OMPC_nogroup:
+ case OMPC_num_tasks:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -6064,6 +6105,7 @@
case OMPC_thread_limit:
case OMPC_priority:
case OMPC_grainsize:
+ case OMPC_num_tasks:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -6203,6 +6245,7 @@
case OMPC_priority:
case OMPC_grainsize:
case OMPC_nogroup:
+ case OMPC_num_tasks:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -8184,3 +8227,20 @@
return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
}
+
+OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ Expr *ValExpr = NumTasks;
+
+ // OpenMP [2.9.2, taskloop Constrcut]
+ // The parameter of the num_tasks clause must be a positive integer
+ // expression.
+ if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
+ /*StrictlyPositive=*/true))
+ return nullptr;
+
+ return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+}
+