diff options
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 189 |
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 |