|
@@ -1568,6 +1568,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
|
|
Params);
|
|
Params);
|
|
break;
|
|
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_threadprivate:
|
|
case OMPD_taskyield:
|
|
case OMPD_taskyield:
|
|
case OMPD_barrier:
|
|
case OMPD_barrier:
|
|
@@ -1652,6 +1660,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | parallel | cancel | ! |
|
|
// | parallel | cancel | ! |
|
|
// | parallel | taskloop | * |
|
|
// | parallel | taskloop | * |
|
|
// | parallel | taskloop simd | * |
|
|
// | parallel | taskloop simd | * |
|
|
|
|
+ // | parallel | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | for | parallel | * |
|
|
// | for | parallel | * |
|
|
// | for | for | + |
|
|
// | for | for | + |
|
|
@@ -1680,6 +1689,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | for | cancel | ! |
|
|
// | for | cancel | ! |
|
|
// | for | taskloop | * |
|
|
// | for | taskloop | * |
|
|
// | for | taskloop simd | * |
|
|
// | for | taskloop simd | * |
|
|
|
|
+ // | for | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | master | parallel | * |
|
|
// | master | parallel | * |
|
|
// | master | for | + |
|
|
// | master | for | + |
|
|
@@ -1708,6 +1718,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | master | cancel | |
|
|
// | master | cancel | |
|
|
// | master | taskloop | * |
|
|
// | master | taskloop | * |
|
|
// | master | taskloop simd | * |
|
|
// | master | taskloop simd | * |
|
|
|
|
+ // | master | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | critical | parallel | * |
|
|
// | critical | parallel | * |
|
|
// | critical | for | + |
|
|
// | critical | for | + |
|
|
@@ -1735,6 +1746,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | critical | cancel | |
|
|
// | critical | cancel | |
|
|
// | critical | taskloop | * |
|
|
// | critical | taskloop | * |
|
|
// | critical | taskloop simd | * |
|
|
// | critical | taskloop simd | * |
|
|
|
|
+ // | critical | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | simd | parallel | |
|
|
// | simd | parallel | |
|
|
// | simd | for | |
|
|
// | simd | for | |
|
|
@@ -1763,6 +1775,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | simd | cancel | |
|
|
// | simd | cancel | |
|
|
// | simd | taskloop | |
|
|
// | simd | taskloop | |
|
|
// | simd | taskloop simd | |
|
|
// | simd | taskloop simd | |
|
|
|
|
+ // | simd | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | for simd | parallel | |
|
|
// | for simd | parallel | |
|
|
// | for simd | for | |
|
|
// | for simd | for | |
|
|
@@ -1791,6 +1804,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | for simd | cancel | |
|
|
// | for simd | cancel | |
|
|
// | for simd | taskloop | |
|
|
// | for simd | taskloop | |
|
|
// | for simd | taskloop simd | |
|
|
// | for simd | taskloop simd | |
|
|
|
|
+ // | for simd | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | parallel for simd| parallel | |
|
|
// | parallel for simd| parallel | |
|
|
// | parallel for simd| for | |
|
|
// | parallel for simd| for | |
|
|
@@ -1819,6 +1833,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | parallel for simd| cancel | |
|
|
// | parallel for simd| cancel | |
|
|
// | parallel for simd| taskloop | |
|
|
// | parallel for simd| taskloop | |
|
|
// | parallel for simd| taskloop simd | |
|
|
// | parallel for simd| taskloop simd | |
|
|
|
|
+ // | parallel for simd| distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | sections | parallel | * |
|
|
// | sections | parallel | * |
|
|
// | sections | for | + |
|
|
// | sections | for | + |
|
|
@@ -1847,6 +1862,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | sections | cancel | ! |
|
|
// | sections | cancel | ! |
|
|
// | sections | taskloop | * |
|
|
// | sections | taskloop | * |
|
|
// | sections | taskloop simd | * |
|
|
// | sections | taskloop simd | * |
|
|
|
|
+ // | sections | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | section | parallel | * |
|
|
// | section | parallel | * |
|
|
// | section | for | + |
|
|
// | section | for | + |
|
|
@@ -1875,6 +1891,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | section | cancel | ! |
|
|
// | section | cancel | ! |
|
|
// | section | taskloop | * |
|
|
// | section | taskloop | * |
|
|
// | section | taskloop simd | * |
|
|
// | section | taskloop simd | * |
|
|
|
|
+ // | section | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | single | parallel | * |
|
|
// | single | parallel | * |
|
|
// | single | for | + |
|
|
// | single | for | + |
|
|
@@ -1903,6 +1920,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | single | cancel | |
|
|
// | single | cancel | |
|
|
// | single | taskloop | * |
|
|
// | single | taskloop | * |
|
|
// | single | taskloop simd | * |
|
|
// | single | taskloop simd | * |
|
|
|
|
+ // | single | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | parallel for | parallel | * |
|
|
// | parallel for | parallel | * |
|
|
// | parallel for | for | + |
|
|
// | parallel for | for | + |
|
|
@@ -1931,6 +1949,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | parallel for | cancel | ! |
|
|
// | parallel for | cancel | ! |
|
|
// | parallel for | taskloop | * |
|
|
// | parallel for | taskloop | * |
|
|
// | parallel for | taskloop simd | * |
|
|
// | parallel for | taskloop simd | * |
|
|
|
|
+ // | parallel for | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | parallel sections| parallel | * |
|
|
// | parallel sections| parallel | * |
|
|
// | parallel sections| for | + |
|
|
// | parallel sections| for | + |
|
|
@@ -1959,6 +1978,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | parallel sections| cancel | ! |
|
|
// | parallel sections| cancel | ! |
|
|
// | parallel sections| taskloop | * |
|
|
// | parallel sections| taskloop | * |
|
|
// | parallel sections| taskloop simd | * |
|
|
// | parallel sections| taskloop simd | * |
|
|
|
|
+ // | parallel sections| distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | task | parallel | * |
|
|
// | task | parallel | * |
|
|
// | task | for | + |
|
|
// | task | for | + |
|
|
@@ -1987,6 +2007,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | task | cancel | ! |
|
|
// | task | cancel | ! |
|
|
// | task | taskloop | * |
|
|
// | task | taskloop | * |
|
|
// | task | taskloop simd | * |
|
|
// | task | taskloop simd | * |
|
|
|
|
+ // | task | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | ordered | parallel | * |
|
|
// | ordered | parallel | * |
|
|
// | ordered | for | + |
|
|
// | ordered | for | + |
|
|
@@ -2015,6 +2036,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | ordered | cancel | |
|
|
// | ordered | cancel | |
|
|
// | ordered | taskloop | * |
|
|
// | ordered | taskloop | * |
|
|
// | ordered | taskloop simd | * |
|
|
// | ordered | taskloop simd | * |
|
|
|
|
+ // | ordered | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | atomic | parallel | |
|
|
// | atomic | parallel | |
|
|
// | atomic | for | |
|
|
// | atomic | for | |
|
|
@@ -2043,6 +2065,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | atomic | cancel | |
|
|
// | atomic | cancel | |
|
|
// | atomic | taskloop | |
|
|
// | atomic | taskloop | |
|
|
// | atomic | taskloop simd | |
|
|
// | atomic | taskloop simd | |
|
|
|
|
+ // | atomic | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | target | parallel | * |
|
|
// | target | parallel | * |
|
|
// | target | for | * |
|
|
// | target | for | * |
|
|
@@ -2071,6 +2094,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | target | cancel | |
|
|
// | target | cancel | |
|
|
// | target | taskloop | * |
|
|
// | target | taskloop | * |
|
|
// | target | taskloop simd | * |
|
|
// | target | taskloop simd | * |
|
|
|
|
+ // | target | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | teams | parallel | * |
|
|
// | teams | parallel | * |
|
|
// | teams | for | + |
|
|
// | teams | for | + |
|
|
@@ -2099,6 +2123,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | teams | cancel | |
|
|
// | teams | cancel | |
|
|
// | teams | taskloop | + |
|
|
// | teams | taskloop | + |
|
|
// | teams | taskloop simd | + |
|
|
// | teams | taskloop simd | + |
|
|
|
|
+ // | teams | distribute | ! |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | taskloop | parallel | * |
|
|
// | taskloop | parallel | * |
|
|
// | taskloop | for | + |
|
|
// | taskloop | for | + |
|
|
@@ -2126,6 +2151,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | | point | |
|
|
// | | point | |
|
|
// | taskloop | cancel | |
|
|
// | taskloop | cancel | |
|
|
// | taskloop | taskloop | * |
|
|
// | taskloop | taskloop | * |
|
|
|
|
+ // | taskloop | distribute | |
|
|
// +------------------+-----------------+------------------------------------+
|
|
// +------------------+-----------------+------------------------------------+
|
|
// | taskloop simd | parallel | |
|
|
// | taskloop simd | parallel | |
|
|
// | taskloop simd | for | |
|
|
// | taskloop simd | for | |
|
|
@@ -2154,6 +2180,36 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// | taskloop simd | cancel | |
|
|
// | taskloop simd | cancel | |
|
|
// | taskloop simd | taskloop | |
|
|
// | taskloop simd | taskloop | |
|
|
// | taskloop simd | taskloop simd | |
|
|
// | 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()) {
|
|
if (Stack->getCurScope()) {
|
|
auto ParentRegion = Stack->getParentDirective();
|
|
auto ParentRegion = Stack->getParentDirective();
|
|
@@ -2163,7 +2219,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
NoRecommend,
|
|
NoRecommend,
|
|
ShouldBeInParallelRegion,
|
|
ShouldBeInParallelRegion,
|
|
ShouldBeInOrderedRegion,
|
|
ShouldBeInOrderedRegion,
|
|
- ShouldBeInTargetRegion
|
|
|
|
|
|
+ ShouldBeInTargetRegion,
|
|
|
|
+ ShouldBeInTeamsRegion
|
|
} Recommend = NoRecommend;
|
|
} Recommend = NoRecommend;
|
|
if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
|
|
if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
|
|
// OpenMP [2.16, Nesting of Regions]
|
|
// OpenMP [2.16, Nesting of Regions]
|
|
@@ -2303,10 +2360,17 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|
// distribute, parallel, parallel sections, parallel workshare, and the
|
|
// distribute, parallel, parallel sections, parallel workshare, and the
|
|
// parallel loop and parallel loop SIMD constructs are the only OpenMP
|
|
// parallel loop and parallel loop SIMD constructs are the only OpenMP
|
|
// constructs that can be closely nested in the teams region.
|
|
// constructs that can be closely nested in the teams region.
|
|
- // TODO: add distribute directive.
|
|
|
|
- NestingProhibited = !isOpenMPParallelDirective(CurrentRegion);
|
|
|
|
|
|
+ NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
|
|
|
|
+ !isOpenMPDistributeDirective(CurrentRegion);
|
|
Recommend = ShouldBeInParallelRegion;
|
|
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) {
|
|
if (NestingProhibited) {
|
|
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
|
|
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
|
|
<< CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend
|
|
<< CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend
|
|
@@ -2574,6 +2638,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|
EndLoc, VarsWithInheritedDSA);
|
|
EndLoc, VarsWithInheritedDSA);
|
|
AllowedNameModifiers.push_back(OMPD_taskloop);
|
|
AllowedNameModifiers.push_back(OMPD_taskloop);
|
|
break;
|
|
break;
|
|
|
|
+ case OMPD_distribute:
|
|
|
|
+ Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
|
|
|
|
+ EndLoc, VarsWithInheritedDSA);
|
|
|
|
+ break;
|
|
case OMPD_threadprivate:
|
|
case OMPD_threadprivate:
|
|
llvm_unreachable("OpenMP Directive is not allowed");
|
|
llvm_unreachable("OpenMP Directive is not allowed");
|
|
case OMPD_unknown:
|
|
case OMPD_unknown:
|
|
@@ -3402,7 +3470,8 @@ static bool CheckOpenMPIterationSpace(
|
|
: OMPC_private;
|
|
: OMPC_private;
|
|
if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
|
|
if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
|
|
DVar.CKind != OMPC_threadprivate && DVar.CKind != PredeterminedCKind) ||
|
|
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 &&
|
|
!isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
|
|
DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate &&
|
|
DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate &&
|
|
DVar.CKind != OMPC_threadprivate)) &&
|
|
DVar.CKind != OMPC_threadprivate)) &&
|
|
@@ -3441,7 +3510,8 @@ static bool CheckOpenMPIterationSpace(
|
|
ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond());
|
|
ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond());
|
|
ResultIterSpace.NumIterations = ISC.BuildNumIterations(
|
|
ResultIterSpace.NumIterations = ISC.BuildNumIterations(
|
|
DSA.getCurScope(), (isOpenMPWorksharingDirective(DKind) ||
|
|
DSA.getCurScope(), (isOpenMPWorksharingDirective(DKind) ||
|
|
- isOpenMPTaskLoopDirective(DKind)));
|
|
|
|
|
|
+ isOpenMPTaskLoopDirective(DKind) ||
|
|
|
|
+ isOpenMPDistributeDirective(DKind)));
|
|
ResultIterSpace.CounterVar = ISC.BuildCounterVar();
|
|
ResultIterSpace.CounterVar = ISC.BuildCounterVar();
|
|
ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
|
|
ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
|
|
ResultIterSpace.CounterInit = ISC.BuildCounterInit();
|
|
ResultIterSpace.CounterInit = ISC.BuildCounterInit();
|
|
@@ -3749,7 +3819,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
|
QualType VType = LastIteration.get()->getType();
|
|
QualType VType = LastIteration.get()->getType();
|
|
// Build variables passed into runtime, nesessary for worksharing directives.
|
|
// Build variables passed into runtime, nesessary for worksharing directives.
|
|
ExprResult LB, UB, IL, ST, EUB;
|
|
ExprResult LB, UB, IL, ST, EUB;
|
|
- if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind)) {
|
|
|
|
|
|
+ if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
|
|
|
|
+ isOpenMPDistributeDirective(DKind)) {
|
|
// Lower bound variable, initialized with zero.
|
|
// Lower bound variable, initialized with zero.
|
|
VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
|
|
VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
|
|
LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
|
|
LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
|
|
@@ -3798,7 +3869,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
|
VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv");
|
|
VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv");
|
|
IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc);
|
|
IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc);
|
|
Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
|
|
Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
|
|
- isOpenMPTaskLoopDirective(DKind))
|
|
|
|
|
|
+ isOpenMPTaskLoopDirective(DKind) ||
|
|
|
|
+ isOpenMPDistributeDirective(DKind))
|
|
? LB.get()
|
|
? LB.get()
|
|
: SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
|
|
: SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
|
|
Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
|
|
Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
|
|
@@ -3808,7 +3880,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
|
// Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
|
|
// Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
|
|
SourceLocation CondLoc;
|
|
SourceLocation CondLoc;
|
|
ExprResult Cond =
|
|
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_LE, IV.get(), UB.get())
|
|
: SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
|
|
: SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
|
|
NumIterations.get());
|
|
NumIterations.get());
|
|
@@ -3828,7 +3901,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
|
// Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
|
|
// Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
|
|
// Used for directives with static scheduling.
|
|
// Used for directives with static scheduling.
|
|
ExprResult NextLB, NextUB;
|
|
ExprResult NextLB, NextUB;
|
|
- if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind)) {
|
|
|
|
|
|
+ if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
|
|
|
|
+ isOpenMPDistributeDirective(DKind)) {
|
|
// LB + ST
|
|
// LB + ST
|
|
NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
|
|
NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
|
|
if (!NextLB.isUsable())
|
|
if (!NextLB.isUsable())
|
|
@@ -5345,6 +5419,32 @@ StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
|
|
NestedLoopCount, Clauses, AStmt, B);
|
|
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,
|
|
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
|
SourceLocation StartLoc,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation LParenLoc,
|
|
@@ -6381,6 +6481,49 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|
continue;
|
|
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.
|
|
// Variably modified types are not supported for tasks.
|
|
@@ -6577,6 +6720,18 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
|
|
if (AssignmentOp.isInvalid())
|
|
if (AssignmentOp.isInvalid())
|
|
continue;
|
|
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)
|
|
if (TopDVar.CKind != OMPC_firstprivate)
|
|
DSAStack->addDSA(VD, DE, OMPC_lastprivate);
|
|
DSAStack->addDSA(VD, DE, OMPC_lastprivate);
|
|
Vars.push_back(DE);
|
|
Vars.push_back(DE);
|