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/Sema/SemaOpenMP.cpp | |
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/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 114 |
1 files changed, 102 insertions, 12 deletions
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, |