Expand Up
@@ -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
Expand Down
Expand Up
@@ -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.
Expand Down
Expand Up
@@ -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 ());
Expand All
@@ -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 ;
Expand Down
Expand Up
@@ -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;
}
Expand All
@@ -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 ,
Expand All
@@ -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 ,
Expand All
@@ -2921,29 +2963,28 @@ 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,
*this , *DSAStack, VarsWithImplicitDSA, B);
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,
Expand Down
Expand Up
@@ -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,
Expand All
@@ -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 (
Expand All
@@ -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),
Expand All
@@ -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
Expand Down