summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
authorCarlo Bertolli <cbertol@us.ibm.com>2016-06-27 14:55:37 +0000
committerCarlo Bertolli <cbertol@us.ibm.com>2016-06-27 14:55:37 +0000
commit9925f15661624adb8c812f9a59b5b52caa31eb89 (patch)
treef2817baf9315001c31b1e2e202fc0916ac3e21ef /clang/lib/Sema/SemaOpenMP.cpp
parentb8dc8485c3a6e86730ac06ba40de47345e1ec278 (diff)
downloadbcm5719-llvm-9925f15661624adb8c812f9a59b5b52caa31eb89.tar.gz
bcm5719-llvm-9925f15661624adb8c812f9a59b5b52caa31eb89.zip
Resubmission of http://reviews.llvm.org/D21564 after fixes.
[OpenMP] Initial implementation of parse and sema for composite pragma 'distribute parallel for' This patch is an initial implementation for #distribute parallel for. The main differences that affect other pragmas are: The implementation of 'distribute parallel for' requires blocking of the associated loop, where blocks are "distributed" to different teams and iterations within each block are scheduled to parallel threads within each team. To implement blocking, sema creates two additional worksharing directive fields that are used to pass the team assigned block lower and upper bounds through the outlined function resulting from 'parallel'. In this way, scheduling for 'for' to threads can use those bounds. As a consequence of blocking, the stride of 'distribute' is not 1 but it is equal to the blocking size. This is returned by the runtime and sema prepares a DistIncrExpr variable to hold that value. As a consequence of blocking, the global upper bound (EnsureUpperBound) expression of the 'for' is not the original loop upper bound (e.g. in for(i = 0 ; i < N; i++) this is 'N') but it is the team-assigned block upper bound. Sema creates a new expression holding the calculation of the actual upper bound for 'for' as UB = min(UB, PrevUB), where UB is the loop upper bound, and PrevUB is the team-assigned block upper bound. llvm-svn: 273884
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp218
1 files changed, 204 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ca84b8cfed1..772b3765e59 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1814,6 +1814,21 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
Params);
break;
}
+ case OMPD_distribute_parallel_for: {
+ QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
+ QualType KmpInt32PtrTy =
+ Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(".global_tid.", KmpInt32PtrTy),
+ std::make_pair(".bound_tid.", KmpInt32PtrTy),
+ std::make_pair(".previous.lb.", Context.getSizeType()),
+ std::make_pair(".previous.ub.", Context.getSizeType()),
+ 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:
@@ -2020,7 +2035,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel | cancel | ! |
// | parallel | taskloop | * |
// | parallel | taskloop simd | * |
- // | parallel | distribute | |
+ // | parallel | distribute | + |
+ // | parallel | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | for | parallel | * |
// | for | for | + |
@@ -2056,7 +2073,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for | cancel | ! |
// | for | taskloop | * |
// | for | taskloop simd | * |
- // | for | distribute | |
+ // | for | distribute | + |
+ // | for | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | master | parallel | * |
// | master | for | + |
@@ -2092,7 +2111,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | master | cancel | |
// | master | taskloop | * |
// | master | taskloop simd | * |
- // | master | distribute | |
+ // | master | distribute | + |
+ // | master | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | critical | parallel | * |
// | critical | for | + |
@@ -2127,7 +2148,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | critical | cancel | |
// | critical | taskloop | * |
// | critical | taskloop simd | * |
- // | critical | distribute | |
+ // | critical | distribute | + |
+ // | critical | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | simd | parallel | |
// | simd | for | |
@@ -2164,6 +2187,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | simd | taskloop | |
// | simd | taskloop simd | |
// | simd | distribute | |
+ // | simd | distribute | |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | for simd | parallel | |
// | for simd | for | |
@@ -2200,6 +2225,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for simd | taskloop | |
// | for simd | taskloop simd | |
// | for simd | distribute | |
+ // | for simd | distribute | |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | parallel for simd| parallel | |
// | parallel for simd| for | |
@@ -2236,6 +2263,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel for simd| taskloop | |
// | parallel for simd| taskloop simd | |
// | parallel for simd| distribute | |
+ // | parallel for simd| distribute | |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | sections | parallel | * |
// | sections | for | + |
@@ -2271,7 +2300,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | sections | cancel | ! |
// | sections | taskloop | * |
// | sections | taskloop simd | * |
- // | sections | distribute | |
+ // | sections | distribute | + |
+ // | sections | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | section | parallel | * |
// | section | for | + |
@@ -2307,7 +2338,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | section | cancel | ! |
// | section | taskloop | * |
// | section | taskloop simd | * |
- // | section | distribute | |
+ // | section | distribute | + |
+ // | section | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | single | parallel | * |
// | single | for | + |
@@ -2343,7 +2376,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | single | cancel | |
// | single | taskloop | * |
// | single | taskloop simd | * |
- // | single | distribute | |
+ // | single | distribute | + |
+ // | single | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | parallel for | parallel | * |
// | parallel for | for | + |
@@ -2379,7 +2414,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel for | cancel | ! |
// | parallel for | taskloop | * |
// | parallel for | taskloop simd | * |
- // | parallel for | distribute | |
+ // | parallel for | distribute | + |
+ // | parallel for | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | parallel sections| parallel | * |
// | parallel sections| for | + |
@@ -2415,7 +2452,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel sections| cancel | ! |
// | parallel sections| taskloop | * |
// | parallel sections| taskloop simd | * |
- // | parallel sections| distribute | |
+ // | parallel sections| distribute | + |
+ // | parallel sections| distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | task | parallel | * |
// | task | for | + |
@@ -2451,7 +2490,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | task | cancel | ! |
// | task | taskloop | * |
// | task | taskloop simd | * |
- // | task | distribute | |
+ // | task | distribute | + |
+ // | task | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | ordered | parallel | * |
// | ordered | for | + |
@@ -2487,7 +2528,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | ordered | cancel | |
// | ordered | taskloop | * |
// | ordered | taskloop simd | * |
- // | ordered | distribute | |
+ // | ordered | distribute | + |
+ // | ordered | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | atomic | parallel | |
// | atomic | for | |
@@ -2524,6 +2567,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | atomic | taskloop | |
// | atomic | taskloop simd | |
// | atomic | distribute | |
+ // | atomic | distribute | |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | target | parallel | * |
// | target | for | * |
@@ -2559,7 +2604,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | target | cancel | |
// | target | taskloop | * |
// | target | taskloop simd | * |
- // | target | distribute | |
+ // | target | distribute | + |
+ // | target | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | target parallel | parallel | * |
// | target parallel | for | * |
@@ -2596,6 +2643,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | target parallel | taskloop | * |
// | target parallel | taskloop simd | * |
// | target parallel | distribute | |
+ // | target parallel | distribute | |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | target parallel | parallel | * |
// | for | | |
@@ -2659,6 +2708,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for | | |
// | target parallel | distribute | |
// | for | | |
+ // | parallel | distribute | |
+ // | for | parallel for | |
// +------------------+-----------------+------------------------------------+
// | teams | parallel | * |
// | teams | for | + |
@@ -2695,6 +2746,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | teams | taskloop | + |
// | teams | taskloop simd | + |
// | teams | distribute | ! |
+ // | teams | distribute | ! |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | taskloop | parallel | * |
// | taskloop | for | + |
@@ -2729,7 +2782,9 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | | point | |
// | taskloop | cancel | |
// | taskloop | taskloop | * |
- // | taskloop | distribute | |
+ // | taskloop | distribute | + |
+ // | taskloop | distribute | + |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | taskloop simd | parallel | |
// | taskloop simd | for | |
@@ -2766,6 +2821,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | taskloop simd | taskloop | |
// | taskloop simd | taskloop simd | |
// | taskloop simd | distribute | |
+ // | taskloop simd | distribute | |
+ // | | parallel for | |
// +------------------+-----------------+------------------------------------+
// | distribute | parallel | * |
// | distribute | for | * |
@@ -2802,6 +2859,74 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | distribute | taskloop | * |
// | distribute | taskloop simd | * |
// | distribute | distribute | |
+ // | distribute | distribute | |
+ // | | parallel for | |
+ // +------------------+-----------------+------------------------------------+
+ // | distribute | parallel | * |
+ // | parallel for | | |
+ // | distribute | for | * |
+ // | parallel for | | |
+ // | distribute | for simd | * |
+ // | parallel for | | |
+ // | distribute | master | * |
+ // | parallel for | | |
+ // | distribute | critical | * |
+ // | parallel for | | |
+ // | distribute | simd | * |
+ // | parallel for | | |
+ // | distribute | sections | * |
+ // | parallel for | | |
+ // | distribute | section | * |
+ // | parallel for | | |
+ // | distribute | single | * |
+ // | parallel for | | |
+ // | distribute | parallel for | * |
+ // | parallel for | | |
+ // | distribute |parallel for simd| * |
+ // | parallel for | | |
+ // | distribute |parallel sections| * |
+ // | parallel for | | |
+ // | distribute | task | * |
+ // | parallel for | | |
+ // | parallel for | | |
+ // | distribute | taskyield | * |
+ // | parallel for | | |
+ // | distribute | barrier | * |
+ // | parallel for | | |
+ // | distribute | taskwait | * |
+ // | parallel for | | |
+ // | distribute | taskgroup | * |
+ // | parallel for | | |
+ // | distribute | flush | * |
+ // | parallel for | | |
+ // | distribute | ordered | + |
+ // | parallel for | | |
+ // | distribute | atomic | * |
+ // | parallel for | | |
+ // | distribute | target | |
+ // | parallel for | | |
+ // | distribute | target parallel | |
+ // | parallel for | | |
+ // | distribute | target parallel | |
+ // | parallel for | for | |
+ // | distribute | target enter | |
+ // | parallel for | data | |
+ // | distribute | target exit | |
+ // | parallel for | data | |
+ // | distribute | teams | |
+ // | parallel for | | |
+ // | distribute | cancellation | + |
+ // | parallel for | point | |
+ // | distribute | cancel | + |
+ // | parallel for | | |
+ // | distribute | taskloop | * |
+ // | parallel for | | |
+ // | distribute | taskloop simd | * |
+ // | parallel for | | |
+ // | distribute | distribute | |
+ // | parallel for | | |
+ // | distribute | distribute | |
+ // | parallel for | parallel for | |
// +------------------+-----------------+------------------------------------+
if (Stack->getCurScope()) {
auto ParentRegion = Stack->getParentDirective();
@@ -3283,6 +3408,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc);
AllowedNameModifiers.push_back(OMPD_target_update);
break;
+ case OMPD_distribute_parallel_for:
+ Res = ActOnOpenMPDistributeParallelForDirective(
+ ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
+ AllowedNameModifiers.push_back(OMPD_parallel);
+ break;
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_threadprivate:
@@ -4790,7 +4920,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
// Build variables passed into runtime, nesessary for worksharing directives.
- ExprResult LB, UB, IL, ST, EUB;
+ ExprResult LB, UB, IL, ST, EUB, PrevLB, PrevUB;
if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
isOpenMPDistributeDirective(DKind)) {
// Lower bound variable, initialized with zero.
@@ -4833,6 +4963,31 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
CondOp.get());
EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
+
+ // If we have a combined directive that combines 'distribute', 'for' or
+ // 'simd' we need to be able to access the bounds of the schedule of the
+ // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
+ // by scheduling 'distribute' have to be passed to the schedule of 'for'.
+ if (isOpenMPLoopBoundSharingDirective(DKind)) {
+ auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
+
+ // We expect to have at least 2 more parameters than the 'parallel'
+ // directive does - the lower and upper bounds of the previous schedule.
+ assert(CD->getNumParams() >= 4 &&
+ "Unexpected number of parameters in loop combined directive");
+
+ // Set the proper type for the bounds given what we learned from the
+ // enclosed loops.
+ auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
+ auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
+
+ // Previous lower and upper bounds are obtained from the region
+ // parameters.
+ PrevLB =
+ buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
+ PrevUB =
+ buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
+ }
}
// Build the iteration variable and its initialization before loop.
@@ -5010,6 +5165,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
Built.EUB = EUB.get();
Built.NLB = NextLB.get();
Built.NUB = NextUB.get();
+ Built.PrevLB = PrevLB.get();
+ Built.PrevUB = PrevUB.get();
Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
// Fill data for doacross depend clauses.
@@ -6732,6 +6889,39 @@ StmtResult Sema::ActOnOpenMPDistributeDirective(
NestedLoopCount, Clauses, AStmt, B);
}
+StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
+ 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' with number of loops, it will
+ // define the nested loops number.
+ unsigned NestedLoopCount = CheckOpenMPLoop(
+ OMPD_distribute_parallel_for, 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 OMPDistributeParallelForDirective::Create(
+ Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
+}
+
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
OpenPOWER on IntegriCloud