summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp189
1 files changed, 113 insertions, 76 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ddd47f58fab..995054321d3 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -2357,46 +2357,6 @@ struct LoopIterationSpace {
SourceRange IncSrcRange;
};
-/// \brief The resulting expressions built for the OpenMP loop CodeGen for the
-/// whole collapsed loop nest. See class OMPLoopDirective for their description.
-struct BuiltLoopExprs {
- Expr *IterationVarRef;
- Expr *LastIteration;
- Expr *CalcLastIteration;
- Expr *PreCond;
- Expr *Cond;
- Expr *SeparatedCond;
- Expr *Init;
- Expr *Inc;
- SmallVector<Expr *, 4> Counters;
- SmallVector<Expr *, 4> Updates;
- SmallVector<Expr *, 4> Finals;
-
- bool builtAll() {
- return IterationVarRef != nullptr && LastIteration != nullptr &&
- PreCond != nullptr && Cond != nullptr && SeparatedCond != nullptr &&
- Init != nullptr && Inc != nullptr;
- }
- void clear(unsigned size) {
- IterationVarRef = nullptr;
- LastIteration = nullptr;
- CalcLastIteration = nullptr;
- PreCond = nullptr;
- Cond = nullptr;
- SeparatedCond = nullptr;
- Init = nullptr;
- Inc = nullptr;
- Counters.resize(size);
- Updates.resize(size);
- Finals.resize(size);
- for (unsigned i = 0; i < size; ++i) {
- Counters[i] = nullptr;
- Updates[i] = nullptr;
- Finals[i] = nullptr;
- }
- }
-};
-
} // namespace
/// \brief Called on a for stmt to check and extract its iteration space
@@ -2613,7 +2573,7 @@ static unsigned
CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA,
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
- BuiltLoopExprs &Built) {
+ OMPLoopDirective::HelperExprs &Built) {
unsigned NestedLoopCount = 1;
if (NestedLoopCountExpr) {
// Found 'collapse' clause - calculate collapse number.
@@ -2750,23 +2710,71 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
CurScope, InitLoc, BO_GT, LastIteration.get(),
SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get());
- // Build the iteration variable and its initialization to zero before loop.
+ QualType VType = LastIteration.get()->getType();
+ // Build variables passed into runtime, nesessary for worksharing directives.
+ ExprResult LB, UB, IL, ST, EUB;
+ if (isOpenMPWorksharingDirective(DKind)) {
+ // Lower bound variable, initialized with zero.
+ VarDecl *LBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
+ LB = SemaRef.BuildDeclRefExpr(LBDecl, VType, VK_LValue, InitLoc);
+ SemaRef.AddInitializerToDecl(
+ LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
+ /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
+
+ // Upper bound variable, initialized with last iteration number.
+ VarDecl *UBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
+ UB = SemaRef.BuildDeclRefExpr(UBDecl, VType, VK_LValue, InitLoc);
+ SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
+ /*DirectInit*/ false,
+ /*TypeMayContainAuto*/ false);
+
+ // A 32-bit variable-flag where runtime returns 1 for the last iteration.
+ // This will be used to implement clause 'lastprivate'.
+ QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
+ VarDecl *ILDecl = BuildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
+ IL = SemaRef.BuildDeclRefExpr(ILDecl, Int32Ty, VK_LValue, InitLoc);
+ SemaRef.AddInitializerToDecl(
+ ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
+ /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
+
+ // Stride variable returned by runtime (we initialize it to 1 by default).
+ VarDecl *STDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.stride");
+ ST = SemaRef.BuildDeclRefExpr(STDecl, VType, VK_LValue, InitLoc);
+ SemaRef.AddInitializerToDecl(
+ STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
+ /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
+
+ // Build expression: UB = min(UB, LastIteration)
+ // It is nesessary for CodeGen of directives with static scheduling.
+ ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
+ UB.get(), LastIteration.get());
+ ExprResult CondOp = SemaRef.ActOnConditionalOp(
+ InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
+ EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
+ CondOp.get());
+ EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
+ }
+
+ // Build the iteration variable and its initialization before loop.
ExprResult IV;
ExprResult Init;
{
- VarDecl *IVDecl = BuildVarDecl(SemaRef, InitLoc,
- LastIteration.get()->getType(), ".omp.iv");
- IV = SemaRef.BuildDeclRefExpr(IVDecl, LastIteration.get()->getType(),
- VK_LValue, InitLoc);
- Init = SemaRef.BuildBinOp(
- CurScope, InitLoc, BO_Assign, IV.get(),
- SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get());
+ VarDecl *IVDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.iv");
+ IV = SemaRef.BuildDeclRefExpr(IVDecl, VType, VK_LValue, InitLoc);
+ Expr *RHS = isOpenMPWorksharingDirective(DKind)
+ ? LB.get()
+ : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
+ Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
+ Init = SemaRef.ActOnFinishFullExpr(Init.get());
}
- // Loop condition (IV < NumIterations)
+ // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
SourceLocation CondLoc;
- ExprResult Cond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
- NumIterations.get());
+ ExprResult Cond =
+ isOpenMPWorksharingDirective(DKind)
+ ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
+ : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
+ NumIterations.get());
// Loop condition with 1 iteration separated (IV < LastIteration)
ExprResult SeparatedCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT,
IV.get(), LastIteration.get());
@@ -2779,6 +2787,35 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
if (!Inc.isUsable())
return 0;
Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
+ Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
+ if (!Inc.isUsable())
+ return 0;
+
+ // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
+ // Used for directives with static scheduling.
+ ExprResult NextLB, NextUB;
+ if (isOpenMPWorksharingDirective(DKind)) {
+ // LB + ST
+ NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
+ if (!NextLB.isUsable())
+ return 0;
+ // LB = LB + ST
+ NextLB =
+ SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
+ NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
+ if (!NextLB.isUsable())
+ return 0;
+ // UB + ST
+ NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
+ if (!NextUB.isUsable())
+ return 0;
+ // UB = UB + ST
+ NextUB =
+ SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
+ NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
+ if (!NextUB.isUsable())
+ return 0;
+ }
// Build updates and final values of the loop counters.
bool HasErrors = false;
@@ -2868,6 +2905,13 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
Built.SeparatedCond = SeparatedCond.get();
Built.Init = Init.get();
Built.Inc = Inc.get();
+ Built.LB = LB.get();
+ Built.UB = UB.get();
+ Built.IL = IL.get();
+ Built.ST = ST.get();
+ Built.EUB = EUB.get();
+ Built.NLB = NextLB.get();
+ Built.NUB = NextUB.get();
return NestedLoopCount;
}
@@ -2887,7 +2931,7 @@ StmtResult Sema::ActOnOpenMPSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
- BuiltLoopExprs B;
+ OMPLoopDirective::HelperExprs B;
// In presence of clause 'collapse', it will define the nested loops number.
unsigned NestedLoopCount =
CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this,
@@ -2899,17 +2943,15 @@ StmtResult Sema::ActOnOpenMPSimdDirective(
"omp simd loop exprs were not built");
getCurFunction()->setHasBranchProtectedScope();
- return OMPSimdDirective::Create(
- Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt,
- B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond,
- B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals);
+ return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+ Clauses, AStmt, B);
}
StmtResult Sema::ActOnOpenMPForDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
- BuiltLoopExprs B;
+ OMPLoopDirective::HelperExprs B;
// In presence of clause 'collapse', it will define the nested loops number.
unsigned NestedLoopCount =
CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this,
@@ -2921,17 +2963,15 @@ StmtResult Sema::ActOnOpenMPForDirective(
"omp for loop exprs were not built");
getCurFunction()->setHasBranchProtectedScope();
- return OMPForDirective::Create(
- Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt,
- B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond,
- B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals);
+ return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+ Clauses, AStmt, B);
}
StmtResult Sema::ActOnOpenMPForSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
- BuiltLoopExprs B;
+ OMPLoopDirective::HelperExprs B;
// In presence of clause 'collapse', it will define the nested loops number.
unsigned NestedLoopCount =
CheckOpenMPLoop(OMPD_for_simd, GetCollapseNumberExpr(Clauses), AStmt,
@@ -2939,11 +2979,12 @@ StmtResult Sema::ActOnOpenMPForSimdDirective(
if (NestedLoopCount == 0)
return StmtError();
+ assert((CurContext->isDependentContext() || B.builtAll()) &&
+ "omp for simd loop exprs were not built");
+
getCurFunction()->setHasBranchProtectedScope();
- return OMPForSimdDirective::Create(
- Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt,
- B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond,
- B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals);
+ return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+ Clauses, AStmt, B);
}
StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
@@ -3036,7 +3077,7 @@ StmtResult Sema::ActOnOpenMPParallelForDirective(
// longjmp() and throw() must not violate the entry/exit criteria.
CS->getCapturedDecl()->setNothrow();
- BuiltLoopExprs B;
+ OMPLoopDirective::HelperExprs B;
// In presence of clause 'collapse', it will define the nested loops number.
unsigned NestedLoopCount =
CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt,
@@ -3048,10 +3089,8 @@ StmtResult Sema::ActOnOpenMPParallelForDirective(
"omp parallel for loop exprs were not built");
getCurFunction()->setHasBranchProtectedScope();
- return OMPParallelForDirective::Create(
- Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt,
- B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond,
- B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals);
+ return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
+ NestedLoopCount, Clauses, AStmt, B);
}
StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
@@ -3067,7 +3106,7 @@ StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
// longjmp() and throw() must not violate the entry/exit criteria.
CS->getCapturedDecl()->setNothrow();
- BuiltLoopExprs B;
+ OMPLoopDirective::HelperExprs B;
// In presence of clause 'collapse', it will define the nested loops number.
unsigned NestedLoopCount =
CheckOpenMPLoop(OMPD_parallel_for_simd, GetCollapseNumberExpr(Clauses),
@@ -3077,9 +3116,7 @@ StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
getCurFunction()->setHasBranchProtectedScope();
return OMPParallelForSimdDirective::Create(
- Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt,
- B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond,
- B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals);
+ Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
}
StmtResult
OpenPOWER on IntegriCloud