diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2015-12-01 04:18:41 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-12-01 04:18:41 +0000 |
| commit | 49f6e78d7118e5411488ebaf134de1fd2ff3f158 (patch) | |
| tree | aacc2c2c6346a501acab425ad933050c7bb0d15f /clang/lib | |
| parent | 1dbaf67537327eb4e34a80c11503bf06e18811e1 (diff) | |
| download | bcm5719-llvm-49f6e78d7118e5411488ebaf134de1fd2ff3f158.tar.gz bcm5719-llvm-49f6e78d7118e5411488ebaf134de1fd2ff3f158.zip | |
[OPENMP 4.5] Parsing/sema analysis for 'taskloop' directive.
Adds initial parsing and semantic analysis for 'taskloop' directive.
llvm-svn: 254367
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 | 4 | ||||
| -rw-r--r-- | clang/lib/Basic/OpenMPKinds.cpp | 14 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 1 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 114 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 11 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 |
13 files changed, 217 insertions, 16 deletions
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index ead92b2b35c..4099b55859b 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -738,3 +738,51 @@ OMPTeamsDirective *OMPTeamsDirective::CreateEmpty(const ASTContext &C, C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *)); return new (Mem) OMPTeamsDirective(NumClauses); } + +OMPTaskLoopDirective *OMPTaskLoopDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, + const HelperExprs &Exprs) { + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskLoopDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = + C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_taskloop)); + OMPTaskLoopDirective *Dir = new (Mem) + OMPTaskLoopDirective(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); + return Dir; +} + +OMPTaskLoopDirective *OMPTaskLoopDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell) { + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskLoopDirective), + llvm::alignOf<OMPClause *>()); + void *Mem = + C.Allocate(Size + sizeof(OMPClause *) * NumClauses + + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_taskloop)); + return new (Mem) OMPTaskLoopDirective(CollapsedNum, NumClauses); +} + diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 8e8ef2297cd..20cf32a8cff 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1029,6 +1029,12 @@ void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) { << getOpenMPDirectiveName(Node->getCancelRegion()) << " "; PrintOMPExecutableDirective(Node); } + +void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) { + Indent() << "#pragma omp taskloop "; + PrintOMPExecutableDirective(Node); +} + //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 511303a5152..3b195aae6c9 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -582,6 +582,10 @@ void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective *S) { VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *S) { + VisitOMPLoopDirective(S); +} + void StmtProfiler::VisitExpr(const Expr *S) { VisitStmt(S); } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 13cd1b928d1..f6bed5412a0 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -410,6 +410,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_taskloop: + switch (CKind) { +#define OPENMP_TASKLOOP_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_unknown: case OMPD_threadprivate: case OMPD_section: @@ -427,8 +437,8 @@ 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; // TODO add next directives. + DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd || + DKind == OMPD_taskloop; // TODO add next directives. } bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 7c4fb4137a9..19c1ceea187 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -256,6 +256,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::OMPTargetDataDirectiveClass: EmitOMPTargetDataDirective(cast<OMPTargetDataDirective>(*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 dd9401b91d2..567c03617c5 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -2542,10 +2542,18 @@ CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) { // Generate the instructions for '#pragma omp target data' directive. void CodeGenFunction::EmitOMPTargetDataDirective( const OMPTargetDataDirective &S) { - // emit the code inside the construct for now auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); CGM.getOpenMPRuntime().emitInlinedDirective( *this, OMPD_target_data, [&CS](CodeGenFunction &CGF) { CGF.EmitStmt(CS->getCapturedStmt()); }); } + +void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) { + // emit the code inside the construct for now + auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); + CGM.getOpenMPRuntime().emitInlinedDirective( + *this, OMPD_taskloop, + [&CS](CodeGenFunction &CGF) { CGF.EmitStmt(CS->getCapturedStmt()); }); +} + diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8a19d5563a4..18ccd4148d0 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2334,6 +2334,7 @@ public: void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S); void EmitOMPCancelDirective(const OMPCancelDirective &S); + void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S); /// \brief Emit inner loop of the worksharing/simd construct. /// diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index cf108011129..22b1d08e697 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -137,6 +137,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { case OMPD_cancellation_point: case OMPD_cancel: case OMPD_target_data: + case OMPD_taskloop: Diag(Tok, diag::err_omp_unexpected_directive) << getOpenMPDirectiveName(DKind); break; @@ -232,7 +233,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { case OMPD_target: case OMPD_teams: case OMPD_taskgroup: - case OMPD_target_data: { + case OMPD_target_data: + case OMPD_taskloop: { ConsumeToken(); // Parse directive name of the 'critical' directive if any. if (DKind == OMPD_critical) { diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index e6f3eb6c85a..ef293babb9f 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -343,7 +343,8 @@ public: }; bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { return isOpenMPParallelDirective(DKind) || DKind == OMPD_task || - isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; + isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown || + DKind == OMPD_taskloop; } } // namespace @@ -1454,6 +1455,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { Params); break; } + case OMPD_taskloop: { + Sema::CapturedParamNameType Params[] = { + std::make_pair(StringRef(), QualType()) // __context with shared vars + }; + ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, + Params); + break; + } case OMPD_threadprivate: case OMPD_taskyield: case OMPD_barrier: @@ -1536,6 +1545,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel | cancellation | | // | | point | ! | // | parallel | cancel | ! | + // | parallel | taskloop | * | // +------------------+-----------------+------------------------------------+ // | for | parallel | * | // | for | for | + | @@ -1562,6 +1572,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | for | cancellation | | // | | point | ! | // | for | cancel | ! | + // | for | taskloop | * | // +------------------+-----------------+------------------------------------+ // | master | parallel | * | // | master | for | + | @@ -1588,6 +1599,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | master | cancellation | | // | | point | | // | master | cancel | | + // | master | taskloop | * | // +------------------+-----------------+------------------------------------+ // | critical | parallel | * | // | critical | for | + | @@ -1613,6 +1625,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | critical | cancellation | | // | | point | | // | critical | cancel | | + // | critical | taskloop | * | // +------------------+-----------------+------------------------------------+ // | simd | parallel | | // | simd | for | | @@ -1639,6 +1652,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | simd | cancellation | | // | | point | | // | simd | cancel | | + // | simd | taskloop | | // +------------------+-----------------+------------------------------------+ // | for simd | parallel | | // | for simd | for | | @@ -1665,6 +1679,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | for simd | cancellation | | // | | point | | // | for simd | cancel | | + // | for simd | taskloop | | // +------------------+-----------------+------------------------------------+ // | parallel for simd| parallel | | // | parallel for simd| for | | @@ -1691,6 +1706,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel for simd| cancellation | | // | | point | | // | parallel for simd| cancel | | + // | parallel for simd| taskloop | | // +------------------+-----------------+------------------------------------+ // | sections | parallel | * | // | sections | for | + | @@ -1717,6 +1733,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | sections | cancellation | | // | | point | ! | // | sections | cancel | ! | + // | sections | taskloop | * | // +------------------+-----------------+------------------------------------+ // | section | parallel | * | // | section | for | + | @@ -1743,6 +1760,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | section | cancellation | | // | | point | ! | // | section | cancel | ! | + // | section | taskloop | * | // +------------------+-----------------+------------------------------------+ // | single | parallel | * | // | single | for | + | @@ -1769,6 +1787,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | single | cancellation | | // | | point | | // | single | cancel | | + // | single | taskloop | * | // +------------------+-----------------+------------------------------------+ // | parallel for | parallel | * | // | parallel for | for | + | @@ -1795,6 +1814,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel for | cancellation | | // | | point | ! | // | parallel for | cancel | ! | + // | parallel for | taskloop | * | // +------------------+-----------------+------------------------------------+ // | parallel sections| parallel | * | // | parallel sections| for | + | @@ -1821,6 +1841,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel sections| cancellation | | // | | point | ! | // | parallel sections| cancel | ! | + // | parallel sections| taskloop | * | // +------------------+-----------------+------------------------------------+ // | task | parallel | * | // | task | for | + | @@ -1847,6 +1868,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | task | cancellation | | // | | point | ! | // | task | cancel | ! | + // | task | taskloop | * | // +------------------+-----------------+------------------------------------+ // | ordered | parallel | * | // | ordered | for | + | @@ -1873,6 +1895,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | ordered | cancellation | | // | | point | | // | ordered | cancel | | + // | ordered | taskloop | * | // +------------------+-----------------+------------------------------------+ // | atomic | parallel | | // | atomic | for | | @@ -1899,6 +1922,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | atomic | cancellation | | // | | point | | // | atomic | cancel | | + // | atomic | taskloop | | // +------------------+-----------------+------------------------------------+ // | target | parallel | * | // | target | for | * | @@ -1925,6 +1949,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | target | cancellation | | // | | point | | // | target | cancel | | + // | target | taskloop | * | // +------------------+-----------------+------------------------------------+ // | teams | parallel | * | // | teams | for | + | @@ -1951,6 +1976,34 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | teams | cancellation | | // | | point | | // | teams | cancel | | + // | teams | taskloop | + | + // +------------------+-----------------+------------------------------------+ + // | taskloop | parallel | * | + // | taskloop | for | + | + // | taskloop | for simd | + | + // | taskloop | master | + | + // | taskloop | critical | * | + // | taskloop | simd | * | + // | taskloop | sections | + | + // | taskloop | section | + | + // | taskloop | single | + | + // | taskloop | parallel for | * | + // | taskloop |parallel for simd| * | + // | taskloop |parallel sections| * | + // | taskloop | task | * | + // | taskloop | taskyield | * | + // | taskloop | barrier | + | + // | taskloop | taskwait | * | + // | taskloop | taskgroup | * | + // | taskloop | flush | * | + // | taskloop | ordered | + | + // | taskloop | atomic | * | + // | taskloop | target | * | + // | taskloop | teams | + | + // | taskloop | cancellation | | + // | | point | | + // | taskloop | cancel | | + // | taskloop | taskloop | * | // +------------------+-----------------+------------------------------------+ if (Stack->getCurScope()) { auto ParentRegion = Stack->getParentDirective(); @@ -2021,7 +2074,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // A master region may not be closely nested inside a worksharing, // atomic, or explicit task region. NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || - ParentRegion == OMPD_task; + ParentRegion == OMPD_task || + ParentRegion == OMPD_taskloop; } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { // OpenMP [2.16, Nesting of Regions] // A critical region may not be nested (closely or otherwise) inside a @@ -2058,7 +2112,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || ParentRegion == OMPD_task || ParentRegion == OMPD_master || - ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; + ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered || + ParentRegion == OMPD_taskloop; } else if (isOpenMPWorksharingDirective(CurrentRegion) && !isOpenMPParallelDirective(CurrentRegion)) { // OpenMP [2.16, Nesting of Regions] @@ -2067,7 +2122,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || ParentRegion == OMPD_task || ParentRegion == OMPD_master || - ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; + ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered || + ParentRegion == OMPD_taskloop; Recommend = ShouldBeInParallelRegion; } else if (CurrentRegion == OMPD_ordered) { // OpenMP [2.16, Nesting of Regions] @@ -2080,6 +2136,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // that can appear in the simd region. NestingProhibited = ParentRegion == OMPD_critical || ParentRegion == OMPD_task || + ParentRegion == OMPD_taskloop || !(isOpenMPSimdDirective(ParentRegion) || Stack->isParentOrderedRegion()); Recommend = ShouldBeInOrderedRegion; @@ -2357,6 +2414,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( EndLoc); AllowedNameModifiers.push_back(OMPD_target_data); break; + case OMPD_taskloop: + Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, + EndLoc, VarsWithInheritedDSA); + AllowedNameModifiers.push_back(OMPD_taskloop); + break; case OMPD_threadprivate: llvm_unreachable("OpenMP Directive is not allowed"); case OMPD_unknown: @@ -3185,9 +3247,10 @@ static bool CheckOpenMPIterationSpace( : OMPC_private; if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_threadprivate && DVar.CKind != PredeterminedCKind) || - (isOpenMPWorksharingDirective(DKind) && !isOpenMPSimdDirective(DKind) && - DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && - DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_threadprivate)) && + ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop) && + !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && + DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate && + DVar.CKind != OMPC_threadprivate)) && ((DVar.CKind != OMPC_private && DVar.CKind != OMPC_threadprivate) || DVar.RefExpr != nullptr)) { SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) @@ -3222,7 +3285,8 @@ static bool CheckOpenMPIterationSpace( // Build the loop's iteration space representation. ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond()); ResultIterSpace.NumIterations = ISC.BuildNumIterations( - DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); + DSA.getCurScope(), + (isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop)); ResultIterSpace.CounterVar = ISC.BuildCounterVar(); ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); ResultIterSpace.CounterInit = ISC.BuildCounterInit(); @@ -3530,7 +3594,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, QualType VType = LastIteration.get()->getType(); // Build variables passed into runtime, nesessary for worksharing directives. ExprResult LB, UB, IL, ST, EUB; - if (isOpenMPWorksharingDirective(DKind)) { + if ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop)) { // Lower bound variable, initialized with zero. VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); @@ -3578,7 +3642,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, { VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc); - Expr *RHS = isOpenMPWorksharingDirective(DKind) + Expr *RHS = (isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop) ? LB.get() : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); @@ -3588,7 +3652,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. SourceLocation CondLoc; ExprResult Cond = - isOpenMPWorksharingDirective(DKind) + (isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop) ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get()); @@ -3608,7 +3672,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). // Used for directives with static scheduling. ExprResult NextLB, NextUB; - if (isOpenMPWorksharingDirective(DKind)) { + if (isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop) { // LB + ST NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); if (!NextLB.isUsable()) @@ -5067,6 +5131,32 @@ StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, CancelRegion); } +StmtResult Sema::ActOnOpenMPTaskLoopDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); + 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_taskloop, getCollapseNumberExpr(Clauses), + getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, + VarsWithImplicitDSA, B); + if (NestedLoopCount == 0) + return StmtError(); + + assert((CurContext->isDependentContext() || B.builtAll()) && + "omp for loop exprs were not built"); + + getCurFunction()->setHasBranchProtectedScope(); + return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, + NestedLoopCount, Clauses, AStmt, B); +} + OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index f839c90da87..589f5114cd6 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7342,6 +7342,17 @@ TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) { return Res; } +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop, DirName, nullptr, + D->getLocStart()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + //===----------------------------------------------------------------------===// // OpenMP clause transformation //===----------------------------------------------------------------------===// diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 49f06f23151..4c86219c004 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2412,6 +2412,10 @@ void ASTStmtReader::VisitOMPCancelDirective(OMPCancelDirective *D) { D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record[Idx++])); } +void ASTStmtReader::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) { + VisitOMPLoopDirective(D); +} + //===----------------------------------------------------------------------===// // ASTReader Implementation //===----------------------------------------------------------------------===// @@ -3034,6 +3038,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, Record[ASTStmtReader::NumStmtFields], Empty); break; + case STMT_OMP_TASKLOOP_DIRECTIVE: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1]; + S = OMPTaskLoopDirective::CreateEmpty(Context, NumClauses, CollapsedNum, + Empty); + break; + } + case EXPR_CXX_OPERATOR_CALL: S = new (Context) CXXOperatorCallExpr(Context, Empty); break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index acb3a7f2cc0..3cf7b18a57b 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2239,6 +2239,11 @@ void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) { Code = serialization::STMT_OMP_CANCEL_DIRECTIVE; } +void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) { + VisitOMPLoopDirective(D); + Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE; +} + //===----------------------------------------------------------------------===// // ASTWriter Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 32f055b8c4b..98e7c3b01a3 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -829,6 +829,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPTeamsDirectiveClass: case Stmt::OMPCancellationPointDirectiveClass: case Stmt::OMPCancelDirectiveClass: + case Stmt::OMPTaskLoopDirectiveClass: llvm_unreachable("Stmt should not be in analyzer evaluation loop"); case Stmt::ObjCSubscriptRefExprClass: |

