diff options
author | Carlo Bertolli <cbertol@us.ibm.com> | 2015-12-14 14:51:25 +0000 |
---|---|---|
committer | Carlo Bertolli <cbertol@us.ibm.com> | 2015-12-14 14:51:25 +0000 |
commit | 6200a3d0f3a545798a0a3abd11ae287a86c9b713 (patch) | |
tree | 6fd952bd07146ac63291c2914cef8694e136d650 /clang/lib/Sema/SemaOpenMP.cpp | |
parent | bc9d4f9947ee5cd2dc686547477f77797a895b3e (diff) | |
download | bcm5719-llvm-6200a3d0f3a545798a0a3abd11ae287a86c9b713.tar.gz bcm5719-llvm-6200a3d0f3a545798a0a3abd11ae287a86c9b713.zip |
Add parse and sema of OpenMP distribute directive with all clauses except dist_schedule
llvm-svn: 255498
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 173 |
1 files changed, 164 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 90aaeaa8afc..45d56d405f2 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1552,6 +1552,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { Params); break; } + case OMPD_distribute: { + 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: @@ -1636,6 +1644,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel | cancel | ! | // | parallel | taskloop | * | // | parallel | taskloop simd | * | + // | parallel | distribute | | // +------------------+-----------------+------------------------------------+ // | for | parallel | * | // | for | for | + | @@ -1664,6 +1673,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | for | cancel | ! | // | for | taskloop | * | // | for | taskloop simd | * | + // | for | distribute | | // +------------------+-----------------+------------------------------------+ // | master | parallel | * | // | master | for | + | @@ -1692,6 +1702,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | master | cancel | | // | master | taskloop | * | // | master | taskloop simd | * | + // | master | distribute | | // +------------------+-----------------+------------------------------------+ // | critical | parallel | * | // | critical | for | + | @@ -1719,6 +1730,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | critical | cancel | | // | critical | taskloop | * | // | critical | taskloop simd | * | + // | critical | distribute | | // +------------------+-----------------+------------------------------------+ // | simd | parallel | | // | simd | for | | @@ -1747,6 +1759,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | simd | cancel | | // | simd | taskloop | | // | simd | taskloop simd | | + // | simd | distribute | | // +------------------+-----------------+------------------------------------+ // | for simd | parallel | | // | for simd | for | | @@ -1775,6 +1788,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | for simd | cancel | | // | for simd | taskloop | | // | for simd | taskloop simd | | + // | for simd | distribute | | // +------------------+-----------------+------------------------------------+ // | parallel for simd| parallel | | // | parallel for simd| for | | @@ -1803,6 +1817,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel for simd| cancel | | // | parallel for simd| taskloop | | // | parallel for simd| taskloop simd | | + // | parallel for simd| distribute | | // +------------------+-----------------+------------------------------------+ // | sections | parallel | * | // | sections | for | + | @@ -1831,6 +1846,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | sections | cancel | ! | // | sections | taskloop | * | // | sections | taskloop simd | * | + // | sections | distribute | | // +------------------+-----------------+------------------------------------+ // | section | parallel | * | // | section | for | + | @@ -1859,6 +1875,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | section | cancel | ! | // | section | taskloop | * | // | section | taskloop simd | * | + // | section | distribute | | // +------------------+-----------------+------------------------------------+ // | single | parallel | * | // | single | for | + | @@ -1887,6 +1904,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | single | cancel | | // | single | taskloop | * | // | single | taskloop simd | * | + // | single | distribute | | // +------------------+-----------------+------------------------------------+ // | parallel for | parallel | * | // | parallel for | for | + | @@ -1915,6 +1933,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel for | cancel | ! | // | parallel for | taskloop | * | // | parallel for | taskloop simd | * | + // | parallel for | distribute | | // +------------------+-----------------+------------------------------------+ // | parallel sections| parallel | * | // | parallel sections| for | + | @@ -1943,6 +1962,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel sections| cancel | ! | // | parallel sections| taskloop | * | // | parallel sections| taskloop simd | * | + // | parallel sections| distribute | | // +------------------+-----------------+------------------------------------+ // | task | parallel | * | // | task | for | + | @@ -1971,6 +1991,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | task | cancel | ! | // | task | taskloop | * | // | task | taskloop simd | * | + // | task | distribute | | // +------------------+-----------------+------------------------------------+ // | ordered | parallel | * | // | ordered | for | + | @@ -1999,6 +2020,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | ordered | cancel | | // | ordered | taskloop | * | // | ordered | taskloop simd | * | + // | ordered | distribute | | // +------------------+-----------------+------------------------------------+ // | atomic | parallel | | // | atomic | for | | @@ -2027,6 +2049,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | atomic | cancel | | // | atomic | taskloop | | // | atomic | taskloop simd | | + // | atomic | distribute | | // +------------------+-----------------+------------------------------------+ // | target | parallel | * | // | target | for | * | @@ -2055,6 +2078,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | target | cancel | | // | target | taskloop | * | // | target | taskloop simd | * | + // | target | distribute | | // +------------------+-----------------+------------------------------------+ // | teams | parallel | * | // | teams | for | + | @@ -2083,6 +2107,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | teams | cancel | | // | teams | taskloop | + | // | teams | taskloop simd | + | + // | teams | distribute | ! | // +------------------+-----------------+------------------------------------+ // | taskloop | parallel | * | // | taskloop | for | + | @@ -2110,6 +2135,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | | point | | // | taskloop | cancel | | // | taskloop | taskloop | * | + // | taskloop | distribute | | // +------------------+-----------------+------------------------------------+ // | taskloop simd | parallel | | // | taskloop simd | for | | @@ -2138,6 +2164,36 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | taskloop simd | cancel | | // | taskloop simd | taskloop | | // | taskloop simd | taskloop simd | | + // | taskloop simd | distribute | | + // +------------------+-----------------+------------------------------------+ + // | distribute | parallel | * | + // | distribute | for | * | + // | distribute | for simd | * | + // | distribute | master | * | + // | distribute | critical | * | + // | distribute | simd | * | + // | distribute | sections | * | + // | distribute | section | * | + // | distribute | single | * | + // | distribute | parallel for | * | + // | distribute |parallel for simd| * | + // | distribute |parallel sections| * | + // | distribute | task | * | + // | distribute | taskyield | * | + // | distribute | barrier | * | + // | distribute | taskwait | * | + // | distribute | taskgroup | * | + // | distribute | flush | * | + // | distribute | ordered | + | + // | distribute | atomic | * | + // | distribute | target | | + // | distribute | teams | | + // | distribute | cancellation | + | + // | | point | | + // | distribute | cancel | + | + // | distribute | taskloop | * | + // | distribute | taskloop simd | * | + // | distribute | distribute | | // +------------------+-----------------+------------------------------------+ if (Stack->getCurScope()) { auto ParentRegion = Stack->getParentDirective(); @@ -2147,7 +2203,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, NoRecommend, ShouldBeInParallelRegion, ShouldBeInOrderedRegion, - ShouldBeInTargetRegion + ShouldBeInTargetRegion, + ShouldBeInTeamsRegion } Recommend = NoRecommend; if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { // OpenMP [2.16, Nesting of Regions] @@ -2287,10 +2344,17 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // distribute, parallel, parallel sections, parallel workshare, and the // parallel loop and parallel loop SIMD constructs are the only OpenMP // constructs that can be closely nested in the teams region. - // TODO: add distribute directive. - NestingProhibited = !isOpenMPParallelDirective(CurrentRegion); + NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && + !isOpenMPDistributeDirective(CurrentRegion); Recommend = ShouldBeInParallelRegion; } + if (!NestingProhibited && isOpenMPDistributeDirective(CurrentRegion)) { + // OpenMP 4.5 [2.17 Nesting of Regions] + // The region associated with the distribute construct must be strictly + // nested inside a teams region + NestingProhibited = !isOpenMPTeamsDirective(ParentRegion); + Recommend = ShouldBeInTeamsRegion; + } if (NestingProhibited) { SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend @@ -2558,6 +2622,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( EndLoc, VarsWithInheritedDSA); AllowedNameModifiers.push_back(OMPD_taskloop); break; + case OMPD_distribute: + Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, + EndLoc, VarsWithInheritedDSA); + break; case OMPD_threadprivate: llvm_unreachable("OpenMP Directive is not allowed"); case OMPD_unknown: @@ -3386,7 +3454,8 @@ static bool CheckOpenMPIterationSpace( : OMPC_private; if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_threadprivate && DVar.CKind != PredeterminedCKind) || - ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop) && + ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || + isOpenMPDistributeDirective(DKind)) && !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_threadprivate)) && @@ -3425,7 +3494,8 @@ static bool CheckOpenMPIterationSpace( ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond()); ResultIterSpace.NumIterations = ISC.BuildNumIterations( DSA.getCurScope(), (isOpenMPWorksharingDirective(DKind) || - isOpenMPTaskLoopDirective(DKind))); + isOpenMPTaskLoopDirective(DKind) || + isOpenMPDistributeDirective(DKind))); ResultIterSpace.CounterVar = ISC.BuildCounterVar(); ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); ResultIterSpace.CounterInit = ISC.BuildCounterInit(); @@ -3733,7 +3803,8 @@ 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) || isOpenMPTaskLoopDirective(DKind)) { + if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || + isOpenMPDistributeDirective(DKind)) { // Lower bound variable, initialized with zero. VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); @@ -3782,7 +3853,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc); Expr *RHS = (isOpenMPWorksharingDirective(DKind) || - isOpenMPTaskLoopDirective(DKind)) + isOpenMPTaskLoopDirective(DKind) || + isOpenMPDistributeDirective(DKind)) ? LB.get() : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); @@ -3792,7 +3864,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. SourceLocation CondLoc; ExprResult Cond = - (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind)) + (isOpenMPWorksharingDirective(DKind) || + isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get()); @@ -3812,7 +3885,8 @@ 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) || isOpenMPTaskLoopDirective(DKind)) { + if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || + isOpenMPDistributeDirective(DKind)) { // LB + ST NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); if (!NextLB.isUsable()) @@ -5365,6 +5439,32 @@ StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( NestedLoopCount, Clauses, AStmt, B); } +StmtResult Sema::ActOnOpenMPDistributeDirective( + 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' with number of loops, it will + // define the nested loops number. + unsigned NestedLoopCount = + CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), + nullptr /*ordered not a clause on distribute*/, 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 OMPDistributeDirective::Create(Context, StartLoc, EndLoc, + NestedLoopCount, Clauses, AStmt, B); +} + OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -6408,6 +6508,49 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, continue; } } + + // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] + // A list item that is private within a teams region must not appear in a + // firstprivate clause on a distribute construct if any of the distribute + // regions arising from the distribute construct ever bind to any of the + // teams regions arising from the teams construct. + // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] + // A list item that appears in a reduction clause of a teams construct + // must not appear in a firstprivate clause on a distribute construct if + // any of the distribute regions arising from the distribute construct + // ever bind to any of the teams regions arising from the teams construct. + // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] + // A list item may appear in a firstprivate or lastprivate clause but not + // both. + if (CurrDir == OMPD_distribute) { + DVar = DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_private), + [](OpenMPDirectiveKind K) -> bool { + return isOpenMPTeamsDirective(K); + }, + false); + if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { + Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); + ReportOriginalDSA(*this, DSAStack, VD, DVar); + continue; + } + DVar = DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), + [](OpenMPDirectiveKind K) -> bool { + return isOpenMPTeamsDirective(K); + }, + false); + if (DVar.CKind == OMPC_reduction && + isOpenMPTeamsDirective(DVar.DKind)) { + Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); + ReportOriginalDSA(*this, DSAStack, VD, DVar); + continue; + } + DVar = DSAStack->getTopDSA(VD, false); + if (DVar.CKind == OMPC_lastprivate) { + Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); + ReportOriginalDSA(*this, DSAStack, VD, DVar); + continue; + } + } } // Variably modified types are not supported for tasks. @@ -6604,6 +6747,18 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, if (AssignmentOp.isInvalid()) continue; + // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] + // A list item may appear in a firstprivate or lastprivate clause but not + // both. + if (CurrDir == OMPD_distribute) { + DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); + if (DVar.CKind == OMPC_firstprivate) { + Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); + ReportOriginalDSA(*this, DSAStack, VD, DVar); + continue; + } + } + if (TopDVar.CKind != OMPC_firstprivate) DSAStack->addDSA(VD, DE, OMPC_lastprivate); Vars.push_back(DE); |