summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2014-07-07 13:01:15 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2014-07-07 13:01:15 +0000
commit4acb859fbdad4b5bc9208d3bfaea6847a682e26f (patch)
tree9e7b794b1f6f141bc4141dbb84cc0d9a1a9e830a /clang/lib/Sema/SemaOpenMP.cpp
parent8a8b850c98f392ec21d5b1e99338e0145d57fe69 (diff)
downloadbcm5719-llvm-4acb859fbdad4b5bc9208d3bfaea6847a682e26f.tar.gz
bcm5719-llvm-4acb859fbdad4b5bc9208d3bfaea6847a682e26f.zip
[OPENMP] Added initial support for 'omp parallel for'.
llvm-svn: 212453
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp151
1 files changed, 122 insertions, 29 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b1786fed0bc..5ce0c84f84a 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -835,6 +835,7 @@ class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
bool ErrorFound;
CapturedStmt *CS;
llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
+ llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
public:
void VisitDeclRefExpr(DeclRefExpr *E) {
@@ -858,9 +859,9 @@ public:
// attribute, must have its data-sharing attribute explicitly determined
// by being listed in a data-sharing attribute clause.
if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
- (isOpenMPParallelDirective(DKind) || DKind == OMPD_task)) {
- ErrorFound = true;
- SemaRef.Diag(ELoc, diag::err_omp_no_dsa_for_variable) << VD;
+ (isOpenMPParallelDirective(DKind) || DKind == OMPD_task) &&
+ VarsWithInheritedDSA.count(VD) == 0) {
+ VarsWithInheritedDSA[VD] = E;
return;
}
@@ -900,6 +901,9 @@ public:
bool isErrorFound() { return ErrorFound; }
ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
+ llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
+ return VarsWithInheritedDSA;
+ }
DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
: Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
@@ -960,6 +964,18 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
Params);
break;
}
+ case OMPD_parallel_for: {
+ QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
+ QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(".global_tid.", KmpInt32PtrTy),
+ std::make_pair(".bound_tid.", KmpInt32PtrTy),
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
+ break;
+ }
case OMPD_threadprivate:
case OMPD_task:
llvm_unreachable("OpenMP Directive is not allowed");
@@ -981,6 +997,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel | sections | * |
// | parallel | section | + |
// | parallel | single | * |
+ // | parallel | parallel for | * |
// +------------------+-----------------+------------------------------------+
// | for | parallel | * |
// | for | for | + |
@@ -988,6 +1005,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for | sections | + |
// | for | section | + |
// | for | single | + |
+ // | for | parallel for | * |
// +------------------+-----------------+------------------------------------+
// | simd | parallel | |
// | simd | for | |
@@ -995,6 +1013,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | simd | sections | |
// | simd | section | |
// | simd | single | |
+ // | simd | parallel for | |
// +------------------+-----------------+------------------------------------+
// | sections | parallel | * |
// | sections | for | + |
@@ -1002,6 +1021,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | sections | sections | + |
// | sections | section | * |
// | sections | single | + |
+ // | sections | parallel for | * |
// +------------------+-----------------+------------------------------------+
// | section | parallel | * |
// | section | for | + |
@@ -1009,6 +1029,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | section | sections | + |
// | section | section | + |
// | section | single | + |
+ // | section | parallel for | * |
// +------------------+-----------------+------------------------------------+
// | single | parallel | * |
// | single | for | + |
@@ -1016,6 +1037,15 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | single | sections | + |
// | single | section | + |
// | single | single | + |
+ // | single | parallel for | * |
+ // +------------------+-----------------+------------------------------------+
+ // | parallel for | parallel | * |
+ // | parallel for | for | + |
+ // | parallel for | simd | * |
+ // | parallel for | sections | + |
+ // | parallel for | section | + |
+ // | parallel for | single | + |
+ // | parallel for | parallel for | * |
// +------------------+-----------------+------------------------------------+
if (Stack->getCurScope()) {
auto ParentRegion = Stack->getParentDirective();
@@ -1079,6 +1109,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
if (DSAChecker.isErrorFound())
return StmtError();
// Generate list of implicitly defined firstprivate variables.
+ auto &VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
@@ -1100,11 +1131,12 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
EndLoc);
break;
case OMPD_simd:
- Res =
- ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
+ Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
+ VarsWithInheritedDSA);
break;
case OMPD_for:
- Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
+ Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
+ VarsWithInheritedDSA);
break;
case OMPD_sections:
Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
@@ -1119,6 +1151,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
EndLoc);
break;
+ case OMPD_parallel_for:
+ Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
+ EndLoc, VarsWithInheritedDSA);
+ break;
case OMPD_threadprivate:
case OMPD_task:
llvm_unreachable("OpenMP Directive is not allowed");
@@ -1126,6 +1162,13 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
llvm_unreachable("Unknown OpenMP directive");
}
+ for (auto P : VarsWithInheritedDSA) {
+ Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
+ << P.first << P.second->getSourceRange();
+ }
+ if (!VarsWithInheritedDSA.empty())
+ return StmtError();
+
if (ErrorFound)
return StmtError();
return Res;
@@ -1512,11 +1555,11 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
/// \brief Called on a for stmt to check and extract its iteration space
/// for further processing (such as collapsing).
-static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S,
- Sema &SemaRef, DSAStackTy &DSA,
- unsigned CurrentNestedLoopCount,
- unsigned NestedLoopCount,
- Expr *NestedLoopCountExpr) {
+static bool CheckOpenMPIterationSpace(
+ OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
+ unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
+ Expr *NestedLoopCountExpr,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
// OpenMP [2.6, Canonical Loop Form]
// for (init-expr; test-expr; incr-expr) structured-block
auto For = dyn_cast_or_null<ForStmt>(S);
@@ -1560,6 +1603,18 @@ static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S,
HasErrors = true;
}
+ // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a
+ // Construct
+ // The loop iteration variable(s) in the associated for-loop(s) of a for or
+ // parallel for construct is (are) private.
+ // The loop iteration variable in the associated for-loop of a simd construct
+ // with just one associated for-loop is linear with a constant-linear-step
+ // that is the increment of the associated for-loop.
+ // Exclude loop var from the list of variables with implicitly defined data
+ // sharing attributes.
+ while (VarsWithImplicitDSA.count(Var) > 0)
+ VarsWithImplicitDSA.erase(Var);
+
// OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in
// a Construct, C/C++].
// The loop iteration variable in the associated for-loop of a simd construct
@@ -1568,18 +1623,25 @@ static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S,
// The loop iteration variable(s) in the associated for-loop(s) of a for or
// parallel for construct may be listed in a private or lastprivate clause.
DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var);
+ auto PredeterminedCKind =
+ isOpenMPSimdDirective(DKind)
+ ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
+ : OMPC_private;
if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
- DVar.CKind != OMPC_linear && DVar.CKind != OMPC_lastprivate) ||
+ DVar.CKind != PredeterminedCKind) ||
(isOpenMPWorksharingDirective(DKind) && DVar.CKind != OMPC_unknown &&
DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
(DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
+ << getOpenMPClauseName(PredeterminedCKind);
ReportOriginalDSA(SemaRef, &DSA, Var, DVar, true);
HasErrors = true;
} else {
- // Make the loop iteration variable private by default.
- DSA.addDSA(Var, nullptr, OMPC_private);
+ // Make the loop iteration variable private (for worksharing constructs),
+ // linear (for simd directives with the only one associated loop) or
+ // lastprivate (for simd directives with several collapsed loops).
+ DSA.addDSA(Var, nullptr, PredeterminedCKind);
}
assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
@@ -1624,9 +1686,10 @@ static Stmt *IgnoreContainerStmts(Stmt *S, bool IgnoreCaptured) {
/// \brief Called on a for stmt to check itself and nested loops (if any).
/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
/// number of collapsed loops otherwise.
-static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind,
- Expr *NestedLoopCountExpr, Stmt *AStmt,
- Sema &SemaRef, DSAStackTy &DSA) {
+static unsigned
+CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
+ Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
unsigned NestedLoopCount = 1;
if (NestedLoopCountExpr) {
// Found 'collapse' clause - calculate collapse number.
@@ -1639,7 +1702,8 @@ static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind,
Stmt *CurStmt = IgnoreContainerStmts(AStmt, true);
for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
- NestedLoopCount, NestedLoopCountExpr))
+ NestedLoopCount, NestedLoopCountExpr,
+ VarsWithImplicitDSA))
return 0;
// Move on to the next nested for loop, or to the loop body.
CurStmt = IgnoreContainerStmts(cast<ForStmt>(CurStmt)->getBody(), false);
@@ -1661,12 +1725,14 @@ static Expr *GetCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
return nullptr;
}
-StmtResult Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc) {
+StmtResult Sema::ActOnOpenMPSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
// In presence of clause 'collapse', it will define the nested loops number.
- unsigned NestedLoopCount = CheckOpenMPLoop(
- OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this, *DSAStack);
+ unsigned NestedLoopCount =
+ CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this,
+ *DSAStack, VarsWithImplicitDSA);
if (NestedLoopCount == 0)
return StmtError();
@@ -1675,12 +1741,14 @@ StmtResult Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses,
Clauses, AStmt);
}
-StmtResult Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc) {
+StmtResult Sema::ActOnOpenMPForDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
// In presence of clause 'collapse', it will define the nested loops number.
- unsigned NestedLoopCount = CheckOpenMPLoop(
- OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this, *DSAStack);
+ unsigned NestedLoopCount =
+ CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this,
+ *DSAStack, VarsWithImplicitDSA);
if (NestedLoopCount == 0)
return StmtError();
@@ -1741,6 +1809,31 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
}
+StmtResult Sema::ActOnOpenMPParallelForDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+ assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+ 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();
+
+ // In presence of clause 'collapse', it will define the nested loops number.
+ unsigned NestedLoopCount =
+ CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt,
+ *this, *DSAStack, VarsWithImplicitDSA);
+ if (NestedLoopCount == 0)
+ return StmtError();
+
+ getCurFunction()->setHasBranchProtectedScope();
+ return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
+ NestedLoopCount, Clauses, AStmt);
+}
+
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
OpenPOWER on IntegriCloud