diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/StmtOpenMP.cpp | 48 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Basic/OpenMPKinds.cpp | 29 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 161 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 11 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 7 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 |
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: |