summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-10-14 20:44:34 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-10-14 20:44:34 +0000
commit19c95a313cbc80767602410b60d7e7d48ae90d18 (patch)
tree71b1529474d603ac68c804037eaaccd3017acb52
parent8d744a73b55b545f704906966e86cb28ede2423c (diff)
downloadclang-19c95a313cbc80767602410b60d7e7d48ae90d18.tar.gz
[OPNEMP]Allow num_tasks clause in combined task-based directives.
The expression of the num_tasks clause must be captured in the combined task-based directives, like 'parallel master taskloop' directive. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374819 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/OpenMPClause.h24
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h1
-rw-r--r--lib/AST/OpenMPClause.cpp9
-rw-r--r--lib/AST/StmtProfile.cpp1
-rw-r--r--lib/Sema/SemaOpenMP.cpp19
-rw-r--r--lib/Serialization/ASTReader.cpp1
-rw-r--r--lib/Serialization/ASTWriter.cpp1
-rw-r--r--test/OpenMP/parallel_master_taskloop_ast_print.cpp4
-rw-r--r--test/OpenMP/parallel_master_taskloop_codegen.cpp11
9 files changed, 49 insertions, 22 deletions
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index db780f7ed3..911c1cfb77 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -5375,7 +5375,7 @@ public:
/// \endcode
/// In this example directive '#pragma omp taskloop' has clause 'num_tasks'
/// with single expression '4'.
-class OMPNumTasksClause : public OMPClause {
+class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// Location of '('.
@@ -5391,16 +5391,23 @@ public:
/// Build 'num_tasks' clause.
///
/// \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, SourceLocation StartLoc,
+ OMPNumTasksClause(Expr *Size, Stmt *HelperSize,
+ OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumTasks(Size) {}
+ : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this),
+ LParenLoc(LParenLoc), NumTasks(Size) {
+ setPreInitStmt(HelperSize, CaptureRegion);
+ }
/// Build an empty clause.
explicit OMPNumTasksClause()
- : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()) {}
+ : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()),
+ OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -5417,11 +5424,10 @@ public:
return const_child_range(&NumTasks, &NumTasks + 1);
}
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
+ child_range used_children();
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPNumTasksClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
static bool classof(const OMPClause *T) {
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index ba5232a2f4..09a6f7840d 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -3283,6 +3283,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause(
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause(
OMPNumTasksClause *C) {
+ TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getNumTasks()));
return true;
}
diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp
index b97607f8c6..c1aeaf6a6b 100644
--- a/lib/AST/OpenMPClause.cpp
+++ b/lib/AST/OpenMPClause.cpp
@@ -86,6 +86,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
return static_cast<const OMPDeviceClause *>(C);
case OMPC_grainsize:
return static_cast<const OMPGrainsizeClause *>(C);
+ case OMPC_num_tasks:
+ return static_cast<const OMPNumTasksClause *>(C);
case OMPC_default:
case OMPC_proc_bind:
case OMPC_final:
@@ -116,7 +118,6 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_map:
case OMPC_priority:
case OMPC_nogroup:
- case OMPC_num_tasks:
case OMPC_hint:
case OMPC_defaultmap:
case OMPC_unknown:
@@ -241,6 +242,12 @@ OMPClause::child_range OMPGrainsizeClause::used_children() {
return child_range(&Grainsize, &Grainsize + 1);
}
+OMPClause::child_range OMPNumTasksClause::used_children() {
+ if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
+ return child_range(C, C + 1);
+ return child_range(&NumTasks, &NumTasks + 1);
+}
+
OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,
unsigned NumLoops,
SourceLocation StartLoc,
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 6c65f8a1d0..9c19305a7d 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -745,6 +745,7 @@ void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
Profiler->VisitStmt(C->getGrainsize());
}
void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
+ VistOMPClauseWithPreInit(C);
if (C->getNumTasks())
Profiler->VisitStmt(C->getNumTasks());
}
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 94cd80a4b0..4d6ff009c5 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -4595,12 +4595,16 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
if (isOpenMPParallelDirective(DSAStack->getCurrentDirective()))
break;
continue;
+ case OMPC_num_tasks:
+ // Do not analyze if no parent parallel directive.
+ if (isOpenMPParallelDirective(DSAStack->getCurrentDirective()))
+ break;
+ continue;
case OMPC_ordered:
case OMPC_device:
case OMPC_num_teams:
case OMPC_thread_limit:
case OMPC_priority:
- case OMPC_num_tasks:
case OMPC_hint:
case OMPC_collapse:
case OMPC_safelen:
@@ -10778,6 +10782,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
}
break;
case OMPC_grainsize:
+ case OMPC_num_tasks:
switch (DKind) {
case OMPD_task:
case OMPD_taskloop:
@@ -10881,7 +10886,6 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_map:
case OMPC_priority:
case OMPC_nogroup:
- case OMPC_num_tasks:
case OMPC_hint:
case OMPC_defaultmap:
case OMPC_unknown:
@@ -15952,15 +15956,20 @@ OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
Expr *ValExpr = NumTasks;
+ Stmt *HelperValStmt = nullptr;
+ OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
// 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))
+ if (!isNonNegativeIntegerValue(
+ ValExpr, *this, OMPC_num_tasks,
+ /*StrictlyPositive=*/true, /*BuildCapture=*/true,
+ DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
return nullptr;
- return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+ return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
+ StartLoc, LParenLoc, EndLoc);
}
OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 0a7958f2c2..60be1570bd 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -12940,6 +12940,7 @@ void OMPClauseReader::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
}
void OMPClauseReader::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
+ VisitOMPClauseWithPreInit(C);
C->setNumTasks(Record.readSubExpr());
C->setLParenLoc(Record.readSourceLocation());
}
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 57c9242504..3badff45fb 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -6944,6 +6944,7 @@ void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
}
void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
+ VisitOMPClauseWithPreInit(C);
Record.AddStmt(C->getNumTasks());
Record.AddSourceLocation(C->getLParenLoc());
}
diff --git a/test/OpenMP/parallel_master_taskloop_ast_print.cpp b/test/OpenMP/parallel_master_taskloop_ast_print.cpp
index 8095652de4..23cf67c0a5 100644
--- a/test/OpenMP/parallel_master_taskloop_ast_print.cpp
+++ b/test/OpenMP/parallel_master_taskloop_ast_print.cpp
@@ -60,9 +60,9 @@ int main(int argc, char **argv) {
static int a;
// CHECK: static int a;
#pragma omp taskgroup task_reduction(+: d)
-#pragma omp parallel master taskloop if(parallel: a) default(none) shared(a) final(b) priority(5) num_tasks(argc) reduction(*: g)
+#pragma omp parallel master taskloop if(parallel: a) default(none) shared(a, argc) final(b) priority(5) num_tasks(argc) reduction(*: g)
// CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
- // CHECK-NEXT: #pragma omp parallel master taskloop if(parallel: a) default(none) shared(a) final(b) priority(5) num_tasks(argc) reduction(*: g)
+ // CHECK-NEXT: #pragma omp parallel master taskloop if(parallel: a) default(none) shared(a,argc) final(b) priority(5) num_tasks(argc) reduction(*: g)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/parallel_master_taskloop_codegen.cpp b/test/OpenMP/parallel_master_taskloop_codegen.cpp
index 2a2f4eb598..289687cff2 100644
--- a/test/OpenMP/parallel_master_taskloop_codegen.cpp
+++ b/test/OpenMP/parallel_master_taskloop_codegen.cpp
@@ -15,9 +15,9 @@ int main(int argc, char **argv) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* [[DEFLOC:@.+]])
// CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[DEFLOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*))
// CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[DEFLOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*), i64 [[GRAINSIZE:%.+]])
-// CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[DEFLOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i8***, i64)* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i32* [[ARGC:%.+]], i8*** [[ARGV:%.+]], i64 [[COND:%.+]])
+// CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[DEFLOC]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i8***, i64, i64)* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i32* [[ARGC:%.+]], i8*** [[ARGV:%.+]], i64 [[COND:%.+]], i64 [[NUM_TASKS:%.+]])
// CHECK: call void @__kmpc_serialized_parallel(%struct.ident_t* [[DEFLOC]], i32 [[GTID]])
-// CHECK: call void [[OMP_OUTLINED3]](i32* %{{.+}}, i32* %{{.+}}, i32* [[ARGC]], i8*** [[ARGV]], i64 [[COND]])
+// CHECK: call void [[OMP_OUTLINED3]](i32* %{{.+}}, i32* %{{.+}}, i32* [[ARGC]], i8*** [[ARGV]], i64 [[COND]], i64 [[NUM_TASKS]])
// CHECK: call void @__kmpc_end_serialized_parallel(%struct.ident_t* [[DEFLOC]], i32 [[GTID]])
@@ -132,7 +132,7 @@ int main(int argc, char **argv) {
#pragma omp parallel master taskloop nogroup grainsize(argc)
for (int i = 0; i < 10; ++i)
;
-// CHECK: define internal void [[OMP_OUTLINED3]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, i8*** dereferenceable(8) %{{.+}}, i64 %{{.+}})
+// CHECK: define internal void [[OMP_OUTLINED3]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, i8*** dereferenceable(8) %{{.+}}, i64 %{{.+}}, i64 %{{.+}})
// CHECK: [[RES:%.+]] = call {{.*}}i32 @__kmpc_master(%struct.ident_t* [[DEFLOC]], i32 [[GTID:%.+]])
// CHECK-NEXT: [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0
// CHECK-NEXT: br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]
@@ -151,7 +151,8 @@ int main(int argc, char **argv) {
// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
// CHECK: store i64 1, i64* [[ST]],
// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
-// CHECK: call void @__kmpc_taskloop(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 [[IF_INT]], i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 2, i64 4, i8* null)
+// CHECK: [[NUM_TASKS:%.+]] = zext i32 %{{.+}} to i64
+// CHECK: call void @__kmpc_taskloop(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 [[IF_INT]], i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 2, i64 [[NUM_TASKS]], i8* null)
// CHECK: call void @__kmpc_end_taskgroup(%struct.ident_t* [[DEFLOC]], i32 [[GTID]])
// CHECK-NEXT: call {{.*}}void @__kmpc_end_master(%struct.ident_t* [[DEFLOC]], i32 [[GTID]])
// CHECK-NEXT: br label {{%?}}[[EXIT]]
@@ -176,7 +177,7 @@ int main(int argc, char **argv) {
// CHECK: ret i32 0
int i;
-#pragma omp parallel master taskloop if(argc) shared(argc, argv) collapse(2) num_tasks(4)
+#pragma omp parallel master taskloop if(argc) shared(argc, argv) collapse(2) num_tasks(argc)
for (i = 0; i < argc; ++i)
for (int j = argc; j < argv[argc][argc]; ++j)
;