summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/StmtOpenMP.cpp48
-rw-r--r--clang/lib/AST/StmtPrinter.cpp6
-rw-r--r--clang/lib/AST/StmtProfile.cpp5
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp29
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp3
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp5
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h2
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp9
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp161
-rw-r--r--clang/lib/Sema/TreeTransform.h11
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp14
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp7
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp1
13 files changed, 287 insertions, 14 deletions
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp
index ba0b93c78a0..49fe88eeddf 100644
--- a/clang/lib/AST/StmtOpenMP.cpp
+++ b/clang/lib/AST/StmtOpenMP.cpp
@@ -718,6 +718,54 @@ OMPTargetParallelDirective::CreateEmpty(const ASTContext &C,
return new (Mem) OMPTargetParallelDirective(NumClauses);
}
+OMPTargetParallelForDirective *OMPTargetParallelForDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+ const HelperExprs &Exprs, bool HasCancel) {
+ unsigned Size = llvm::alignTo(sizeof(OMPTargetParallelForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(
+ Size + sizeof(OMPClause *) * Clauses.size() +
+ sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_target_parallel_for));
+ OMPTargetParallelForDirective *Dir = new (Mem) OMPTargetParallelForDirective(
+ StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setIterationVariable(Exprs.IterationVarRef);
+ Dir->setLastIteration(Exprs.LastIteration);
+ Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+ Dir->setPreCond(Exprs.PreCond);
+ Dir->setCond(Exprs.Cond);
+ Dir->setInit(Exprs.Init);
+ Dir->setInc(Exprs.Inc);
+ Dir->setIsLastIterVariable(Exprs.IL);
+ Dir->setLowerBoundVariable(Exprs.LB);
+ Dir->setUpperBoundVariable(Exprs.UB);
+ Dir->setStrideVariable(Exprs.ST);
+ Dir->setEnsureUpperBound(Exprs.EUB);
+ Dir->setNextLowerBound(Exprs.NLB);
+ Dir->setNextUpperBound(Exprs.NUB);
+ Dir->setCounters(Exprs.Counters);
+ Dir->setPrivateCounters(Exprs.PrivateCounters);
+ Dir->setInits(Exprs.Inits);
+ Dir->setUpdates(Exprs.Updates);
+ Dir->setFinals(Exprs.Finals);
+ Dir->setHasCancel(HasCancel);
+ return Dir;
+}
+
+OMPTargetParallelForDirective *
+OMPTargetParallelForDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum, EmptyShell) {
+ unsigned Size = llvm::alignTo(sizeof(OMPTargetParallelForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(
+ Size + sizeof(OMPClause *) * NumClauses +
+ sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_target_parallel_for));
+ return new (Mem) OMPTargetParallelForDirective(CollapsedNum, NumClauses);
+}
+
OMPTargetDataDirective *OMPTargetDataDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 666b72e2ed3..d9c3457f486 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1089,6 +1089,12 @@ void StmtPrinter::VisitOMPTargetParallelDirective(
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPTargetParallelForDirective(
+ OMPTargetParallelForDirective *Node) {
+ Indent() << "#pragma omp target parallel for ";
+ PrintOMPExecutableDirective(Node);
+}
+
void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
Indent() << "#pragma omp teams ";
PrintOMPExecutableDirective(Node);
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index f490a2aba33..d2f241c312a 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -599,6 +599,11 @@ void StmtProfiler::VisitOMPTargetParallelDirective(
VisitOMPExecutableDirective(S);
}
+void StmtProfiler::VisitOMPTargetParallelForDirective(
+ const OMPTargetParallelForDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
VisitOMPExecutableDirective(S);
}
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 523e603ee90..ae509772f35 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -465,6 +465,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_target_parallel_for:
+ switch (CKind) {
+#define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_teams:
switch (CKind) {
#define OPENMP_TEAMS_CLAUSE(Name) \
@@ -552,17 +562,17 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd ||
DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||
- DKind == OMPD_taskloop ||
- DKind == OMPD_taskloop_simd ||
- DKind == OMPD_distribute; // TODO add next directives.
+ DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd ||
+ DKind == OMPD_distribute ||
+ DKind == OMPD_target_parallel_for; // TODO add next directives.
}
bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_for || DKind == OMPD_for_simd ||
DKind == OMPD_sections || DKind == OMPD_section ||
DKind == OMPD_single || DKind == OMPD_parallel_for ||
- DKind == OMPD_parallel_for_simd ||
- DKind == OMPD_parallel_sections; // TODO add next directives.
+ DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||
+ DKind == OMPD_target_parallel_for; // TODO add next directives.
}
bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
@@ -571,14 +581,15 @@ bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_parallel || DKind == OMPD_parallel_for ||
- DKind == OMPD_parallel_for_simd ||
- DKind == OMPD_parallel_sections || DKind == OMPD_target_parallel;
- // TODO add next directives.
+ DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||
+ DKind == OMPD_target_parallel || DKind == OMPD_target_parallel_for;
+ // TODO add next directives.
}
bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
// TODO add next directives.
- return DKind == OMPD_target || DKind == OMPD_target_parallel;
+ return DKind == OMPD_target || DKind == OMPD_target_parallel ||
+ DKind == OMPD_target_parallel_for;
}
bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index c0044de083d..cd49f5404ec 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -265,6 +265,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
case Stmt::OMPTargetParallelDirectiveClass:
EmitOMPTargetParallelDirective(cast<OMPTargetParallelDirective>(*S));
break;
+ case Stmt::OMPTargetParallelForDirectiveClass:
+ EmitOMPTargetParallelForDirective(cast<OMPTargetParallelForDirective>(*S));
+ break;
case Stmt::OMPTaskLoopDirectiveClass:
EmitOMPTaskLoopDirective(cast<OMPTaskLoopDirective>(*S));
break;
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index a43263d4a63..dbfc5e2cb27 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -2715,6 +2715,11 @@ void CodeGenFunction::EmitOMPTargetParallelDirective(
// TODO: codegen for target parallel.
}
+void CodeGenFunction::EmitOMPTargetParallelForDirective(
+ const OMPTargetParallelForDirective &S) {
+ // TODO: codegen for target parallel for.
+}
+
void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
// emit the code inside the construct for now
auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index fa1ceebc34f..def41d28f85 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2344,6 +2344,8 @@ public:
void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S);
void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S);
void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S);
+ void
+ EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S);
void EmitOMPTeamsDirective(const OMPTeamsDirective &S);
void
EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S);
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 2fb53d149cd..25d5935b171 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -45,7 +45,8 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
{OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
{OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
{OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
- {OMPD_target, OMPD_parallel, OMPD_target_parallel}};
+ {OMPD_target, OMPD_parallel, OMPD_target_parallel},
+ {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for}};
auto Tok = P.getCurToken();
auto DKind =
Tok.isAnnotation()
@@ -155,6 +156,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
case OMPD_target_enter_data:
case OMPD_target_exit_data:
case OMPD_target_parallel:
+ case OMPD_target_parallel_for:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_distribute:
@@ -178,9 +180,9 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
/// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
/// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
/// 'for simd' | 'parallel for simd' | 'target' | 'target data' |
-/// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' {clause} |
+/// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
/// 'distribute' | 'target enter data' | 'target exit data' |
-/// 'target parallel'
+/// 'target parallel' | 'target parallel for' {clause}
/// annot_pragma_openmp_end
///
StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
@@ -263,6 +265,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_taskgroup:
case OMPD_target_data:
case OMPD_target_parallel:
+ case OMPD_target_parallel_for:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_distribute: {
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b219e92ebeb..09cbca50696 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1630,7 +1630,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
}
case OMPD_target_data:
case OMPD_target:
- case OMPD_target_parallel: {
+ case OMPD_target_parallel:
+ case OMPD_target_parallel_for: {
Sema::CapturedParamNameType Params[] = {
std::make_pair(StringRef(), QualType()) // __context with shared vars
};
@@ -1807,6 +1808,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel | atomic | * |
// | parallel | target | * |
// | parallel | target parallel | * |
+ // | parallel | target parallel | * |
+ // | | for | |
// | parallel | target enter | * |
// | | data | |
// | parallel | target exit | * |
@@ -1841,6 +1844,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for | atomic | * |
// | for | target | * |
// | for | target parallel | * |
+ // | for | target parallel | * |
+ // | | for | |
// | for | target enter | * |
// | | data | |
// | for | target exit | * |
@@ -1875,6 +1880,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | master | atomic | * |
// | master | target | * |
// | master | target parallel | * |
+ // | master | target parallel | * |
+ // | | for | |
// | master | target enter | * |
// | | data | |
// | master | target exit | * |
@@ -1908,6 +1915,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | critical | atomic | * |
// | critical | target | * |
// | critical | target parallel | * |
+ // | critical | target parallel | * |
+ // | | for | |
// | critical | target enter | * |
// | | data | |
// | critical | target exit | * |
@@ -1942,6 +1951,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | simd | atomic | |
// | simd | target | |
// | simd | target parallel | |
+ // | simd | target parallel | |
+ // | | for | |
// | simd | target enter | |
// | | data | |
// | simd | target exit | |
@@ -1976,6 +1987,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for simd | atomic | |
// | for simd | target | |
// | for simd | target parallel | |
+ // | for simd | target parallel | |
+ // | | for | |
// | for simd | target enter | |
// | | data | |
// | for simd | target exit | |
@@ -2010,6 +2023,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel for simd| atomic | |
// | parallel for simd| target | |
// | parallel for simd| target parallel | |
+ // | parallel for simd| target parallel | |
+ // | | for | |
// | parallel for simd| target enter | |
// | | data | |
// | parallel for simd| target exit | |
@@ -2044,6 +2059,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | sections | atomic | * |
// | sections | target | * |
// | sections | target parallel | * |
+ // | sections | target parallel | * |
+ // | | for | |
// | sections | target enter | * |
// | | data | |
// | sections | target exit | * |
@@ -2078,6 +2095,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | section | atomic | * |
// | section | target | * |
// | section | target parallel | * |
+ // | section | target parallel | * |
+ // | | for | |
// | section | target enter | * |
// | | data | |
// | section | target exit | * |
@@ -2112,6 +2131,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | single | atomic | * |
// | single | target | * |
// | single | target parallel | * |
+ // | single | target parallel | * |
+ // | | for | |
// | single | target enter | * |
// | | data | |
// | single | target exit | * |
@@ -2146,6 +2167,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel for | atomic | * |
// | parallel for | target | * |
// | parallel for | target parallel | * |
+ // | parallel for | target parallel | * |
+ // | | for | |
// | parallel for | target enter | * |
// | | data | |
// | parallel for | target exit | * |
@@ -2180,6 +2203,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel sections| atomic | * |
// | parallel sections| target | * |
// | parallel sections| target parallel | * |
+ // | parallel sections| target parallel | * |
+ // | | for | |
// | parallel sections| target enter | * |
// | | data | |
// | parallel sections| target exit | * |
@@ -2214,6 +2239,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | task | atomic | * |
// | task | target | * |
// | task | target parallel | * |
+ // | task | target parallel | * |
+ // | | for | |
// | task | target enter | * |
// | | data | |
// | task | target exit | * |
@@ -2248,6 +2275,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | ordered | atomic | * |
// | ordered | target | * |
// | ordered | target parallel | * |
+ // | ordered | target parallel | * |
+ // | | for | |
// | ordered | target enter | * |
// | | data | |
// | ordered | target exit | * |
@@ -2282,6 +2311,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | atomic | atomic | |
// | atomic | target | |
// | atomic | target parallel | |
+ // | atomic | target parallel | |
+ // | | for | |
// | atomic | target enter | |
// | | data | |
// | atomic | target exit | |
@@ -2316,6 +2347,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | target | atomic | * |
// | target | target | |
// | target | target parallel | |
+ // | target | target parallel | |
+ // | | for | |
// | target | target enter | |
// | | data | |
// | target | target exit | |
@@ -2350,6 +2383,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | target parallel | atomic | * |
// | target parallel | target | |
// | target parallel | target parallel | |
+ // | target parallel | target parallel | |
+ // | | for | |
// | target parallel | target enter | |
// | | data | |
// | target parallel | target exit | |
@@ -2362,6 +2397,69 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | target parallel | taskloop simd | * |
// | target parallel | distribute | |
// +------------------+-----------------+------------------------------------+
+ // | target parallel | parallel | * |
+ // | for | | |
+ // | target parallel | for | * |
+ // | for | | |
+ // | target parallel | for simd | * |
+ // | for | | |
+ // | target parallel | master | * |
+ // | for | | |
+ // | target parallel | critical | * |
+ // | for | | |
+ // | target parallel | simd | * |
+ // | for | | |
+ // | target parallel | sections | * |
+ // | for | | |
+ // | target parallel | section | * |
+ // | for | | |
+ // | target parallel | single | * |
+ // | for | | |
+ // | target parallel | parallel for | * |
+ // | for | | |
+ // | target parallel |parallel for simd| * |
+ // | for | | |
+ // | target parallel |parallel sections| * |
+ // | for | | |
+ // | target parallel | task | * |
+ // | for | | |
+ // | target parallel | taskyield | * |
+ // | for | | |
+ // | target parallel | barrier | * |
+ // | for | | |
+ // | target parallel | taskwait | * |
+ // | for | | |
+ // | target parallel | taskgroup | * |
+ // | for | | |
+ // | target parallel | flush | * |
+ // | for | | |
+ // | target parallel | ordered | * |
+ // | for | | |
+ // | target parallel | atomic | * |
+ // | for | | |
+ // | target parallel | target | |
+ // | for | | |
+ // | target parallel | target parallel | |
+ // | for | | |
+ // | target parallel | target parallel | |
+ // | for | for | |
+ // | target parallel | target enter | |
+ // | for | data | |
+ // | target parallel | target exit | |
+ // | for | data | |
+ // | target parallel | teams | |
+ // | for | | |
+ // | target parallel | cancellation | |
+ // | for | point | ! |
+ // | target parallel | cancel | ! |
+ // | for | | |
+ // | target parallel | taskloop | * |
+ // | for | | |
+ // | target parallel | taskloop simd | * |
+ // | for | | |
+ // | target parallel | distribute | |
+ // | for | | |
+ // +------------------+-----------------+------------------------------------+
// | teams | parallel | * |
// | teams | for | + |
// | teams | for simd | + |
@@ -2384,6 +2482,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | teams | atomic | + |
// | teams | target | + |
// | teams | target parallel | + |
+ // | teams | target parallel | + |
+ // | | for | |
// | teams | target enter | + |
// | | data | |
// | teams | target exit | + |
@@ -2418,6 +2518,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | taskloop | atomic | * |
// | taskloop | target | * |
// | taskloop | target parallel | * |
+ // | taskloop | target parallel | * |
+ // | | for | |
// | taskloop | target enter | * |
// | | data | |
// | taskloop | target exit | * |
@@ -2451,6 +2553,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | taskloop simd | atomic | |
// | taskloop simd | target | |
// | taskloop simd | target parallel | |
+ // | taskloop simd | target parallel | |
+ // | | for | |
// | taskloop simd | target enter | |
// | | data | |
// | taskloop simd | target exit | |
@@ -2485,6 +2589,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | distribute | atomic | * |
// | distribute | target | |
// | distribute | target parallel | |
+ // | distribute | target parallel | |
+ // | | for | |
// | distribute | target enter | |
// | | data | |
// | distribute | target exit | |
@@ -2561,7 +2667,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
(ParentRegion == OMPD_parallel ||
ParentRegion == OMPD_target_parallel)) ||
(CancelRegion == OMPD_for &&
- (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for)) ||
+ (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
+ ParentRegion == OMPD_target_parallel_for)) ||
(CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
(CancelRegion == OMPD_sections &&
(ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
@@ -2924,6 +3031,12 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
AllowedNameModifiers.push_back(OMPD_target);
AllowedNameModifiers.push_back(OMPD_parallel);
break;
+ case OMPD_target_parallel_for:
+ Res = ActOnOpenMPTargetParallelForDirective(
+ ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
+ AllowedNameModifiers.push_back(OMPD_target);
+ AllowedNameModifiers.push_back(OMPD_parallel);
+ break;
case OMPD_cancellation_point:
assert(ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp cancellation point' directive");
@@ -5710,6 +5823,50 @@ Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
AStmt);
}
+StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
+ if (!AStmt)
+ return StmtError();
+
+ CapturedStmt *CS = cast<CapturedStmt>(AStmt);
+ // 1.2.2 OpenMP Language Terminology
+ // Structured block - An executable statement with a single entry at the
+ // top and a single exit at the bottom.
+ // The point of exit cannot be a branch out of the structured block.
+ // longjmp() and throw() must not violate the entry/exit criteria.
+ CS->getCapturedDecl()->setNothrow();
+
+ OMPLoopDirective::HelperExprs B;
+ // In presence of clause 'collapse' or 'ordered' with number of loops, it will
+ // define the nested loops number.
+ unsigned NestedLoopCount =
+ CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
+ getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
+ VarsWithImplicitDSA, B);
+ if (NestedLoopCount == 0)
+ return StmtError();
+
+ assert((CurContext->isDependentContext() || B.builtAll()) &&
+ "omp target parallel for loop exprs were not built");
+
+ if (!CurContext->isDependentContext()) {
+ // Finalize the clauses that need pre-built expressions for CodeGen.
+ for (auto C : Clauses) {
+ if (auto LC = dyn_cast<OMPLinearClause>(C))
+ if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
+ B.NumIterations, *this, CurScope))
+ return StmtError();
+ }
+ }
+
+ getCurFunction()->setHasBranchProtectedScope();
+ return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
+ NestedLoopCount, Clauses, AStmt,
+ B, DSAStack->isCancelRegion());
+}
+
/// \brief Check for existence of a map clause in the list of clauses.
static bool HasMapClause(ArrayRef<OMPClause *> Clauses) {
for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index e3272eec42c..624839cc944 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -7425,6 +7425,17 @@ StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
}
template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
+ OMPTargetParallelForDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_for, DirName,
+ nullptr, D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
+template <typename Derived>
StmtResult
TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
DeclarationNameInfo DirName;
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index a20b260184d..f9c21e64852 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2489,6 +2489,12 @@ void ASTStmtReader::VisitOMPTargetParallelDirective(
VisitOMPExecutableDirective(D);
}
+void ASTStmtReader::VisitOMPTargetParallelForDirective(
+ OMPTargetParallelForDirective *D) {
+ VisitOMPLoopDirective(D);
+ D->setHasCancel(Record[Idx++]);
+}
+
void ASTStmtReader::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
VisitStmt(D);
// The NumClauses field was read in ReadStmtFromStream.
@@ -3147,6 +3153,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
Context, Record[ASTStmtReader::NumStmtFields], Empty);
break;
+ case STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE: {
+ unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+ unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+ S = OMPTargetParallelForDirective::CreateEmpty(Context, NumClauses,
+ CollapsedNum, Empty);
+ break;
+ }
+
case STMT_OMP_TEAMS_DIRECTIVE:
S = OMPTeamsDirective::CreateEmpty(
Context, Record[ASTStmtReader::NumStmtFields], Empty);
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 08615e113fa..8a6d915d614 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -2246,6 +2246,13 @@ void ASTStmtWriter::VisitOMPTargetParallelDirective(
Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
}
+void ASTStmtWriter::VisitOMPTargetParallelForDirective(
+ OMPTargetParallelForDirective *D) {
+ VisitOMPLoopDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
+ Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE;
+}
+
void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
VisitStmt(D);
VisitOMPExecutableDirective(D);
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 662122e8e64..22b32f84141 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -833,6 +833,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::OMPTargetEnterDataDirectiveClass:
case Stmt::OMPTargetExitDataDirectiveClass:
case Stmt::OMPTargetParallelDirectiveClass:
+ case Stmt::OMPTargetParallelForDirectiveClass:
case Stmt::OMPTeamsDirectiveClass:
case Stmt::OMPCancellationPointDirectiveClass:
case Stmt::OMPCancelDirectiveClass:
OpenPOWER on IntegriCloud