summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/StmtOpenMP.cpp85
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp30
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp531
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp12
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp6
5 files changed, 580 insertions, 84 deletions
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp
index 4e829897ceb..7fda574bae0 100644
--- a/clang/lib/AST/StmtOpenMP.cpp
+++ b/clang/lib/AST/StmtOpenMP.cpp
@@ -72,6 +72,25 @@ void OMPLoopDirective::setFinals(ArrayRef<Expr *> A) {
std::copy(A.begin(), A.end(), getFinals().begin());
}
+void OMPLoopDirective::setDependentCounters(ArrayRef<Expr *> A) {
+ assert(
+ A.size() == getCollapsedNumber() &&
+ "Number of dependent counters is not the same as the collapsed number");
+ llvm::copy(A, getDependentCounters().begin());
+}
+
+void OMPLoopDirective::setDependentInits(ArrayRef<Expr *> A) {
+ assert(A.size() == getCollapsedNumber() &&
+ "Number of dependent inits is not the same as the collapsed number");
+ llvm::copy(A, getDependentInits().begin());
+}
+
+void OMPLoopDirective::setFinalsConditions(ArrayRef<Expr *> A) {
+ assert(A.size() == getCollapsedNumber() &&
+ "Number of finals conditions is not the same as the collapsed number");
+ llvm::copy(A, getFinalsConditions().begin());
+}
+
OMPParallelDirective *OMPParallelDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) {
@@ -122,6 +141,9 @@ OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -170,6 +192,9 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setHasCancel(HasCancel);
return Dir;
@@ -220,6 +245,9 @@ OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -383,6 +411,9 @@ OMPParallelForDirective *OMPParallelForDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setHasCancel(HasCancel);
return Dir;
@@ -432,6 +463,9 @@ OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -772,6 +806,9 @@ OMPTargetParallelForDirective *OMPTargetParallelForDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setHasCancel(HasCancel);
return Dir;
@@ -914,6 +951,9 @@ OMPTaskLoopDirective *OMPTaskLoopDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -963,6 +1003,9 @@ OMPTaskLoopSimdDirective *OMPTaskLoopSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -1011,6 +1054,9 @@ OMPDistributeDirective *OMPDistributeDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -1089,6 +1135,9 @@ OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
@@ -1157,6 +1206,9 @@ OMPDistributeParallelForSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
@@ -1219,6 +1271,9 @@ OMPDistributeSimdDirective *OMPDistributeSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -1271,6 +1326,9 @@ OMPTargetParallelForSimdDirective *OMPTargetParallelForSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -1315,6 +1373,9 @@ OMPTargetSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -1363,6 +1424,9 @@ OMPTeamsDistributeDirective *OMPTeamsDistributeDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -1414,6 +1478,9 @@ OMPTeamsDistributeSimdDirective *OMPTeamsDistributeSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -1471,6 +1538,9 @@ OMPTeamsDistributeParallelForSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
@@ -1540,6 +1610,9 @@ OMPTeamsDistributeParallelForDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
@@ -1628,6 +1701,9 @@ OMPTargetTeamsDistributeDirective *OMPTargetTeamsDistributeDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
@@ -1688,6 +1764,9 @@ OMPTargetTeamsDistributeParallelForDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
@@ -1761,6 +1840,9 @@ OMPTargetTeamsDistributeParallelForSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
@@ -1826,6 +1908,9 @@ OMPTargetTeamsDistributeSimdDirective::Create(
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setDependentCounters(Exprs.DependentCounters);
+ Dir->setDependentInits(Exprs.DependentInits);
+ Dir->setFinalsConditions(Exprs.FinalsConditions);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index e8fbca5108a..2ca7ebc6b0d 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1324,6 +1324,16 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
// On a continue in the body, jump to the end.
JumpDest Continue = getJumpDestInCurrentScope("omp.body.continue");
BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
+ for (const Expr *E : D.finals_conditions()) {
+ if (!E)
+ continue;
+ // Check that loop counter in non-rectangular nest fits into the iteration
+ // space.
+ llvm::BasicBlock *NextBB = createBasicBlock("omp.body.next");
+ EmitBranchOnBoolExpr(E, NextBB, Continue.getBlock(),
+ getProfileCount(D.getBody()));
+ EmitBlock(NextBB);
+ }
// Emit loop body.
EmitStmt(D.getBody());
// The end (updates/cleanups).
@@ -1553,8 +1563,28 @@ static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
CGF.EmitIgnoredExpr(I);
}
}
+ // Create temp loop control variables with their init values to support
+ // non-rectangular loops.
+ CodeGenFunction::OMPMapVars PreCondVars;
+ for (const Expr * E: S.dependent_counters()) {
+ if (!E)
+ continue;
+ assert(!E->getType().getNonReferenceType()->isRecordType() &&
+ "dependent counter must not be an iterator.");
+ const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
+ Address CounterAddr =
+ CGF.CreateMemTemp(VD->getType().getNonReferenceType());
+ (void)PreCondVars.setVarAddr(CGF, VD, CounterAddr);
+ }
+ (void)PreCondVars.apply(CGF);
+ for (const Expr *E : S.dependent_inits()) {
+ if (!E)
+ continue;
+ CGF.EmitIgnoredExpr(E);
+ }
// Check that loop is executed at least one time.
CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount);
+ PreCondVars.restore(CGF);
}
void CodeGenFunction::EmitOMPLinearClause(
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 49c7c3aca14..3c23e43a20a 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4709,6 +4709,54 @@ StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
}
namespace {
+/// Iteration space of a single for loop.
+struct LoopIterationSpace final {
+ /// True if the condition operator is the strict compare operator (<, > or
+ /// !=).
+ bool IsStrictCompare = false;
+ /// Condition of the loop.
+ Expr *PreCond = nullptr;
+ /// This expression calculates the number of iterations in the loop.
+ /// It is always possible to calculate it before starting the loop.
+ Expr *NumIterations = nullptr;
+ /// The loop counter variable.
+ Expr *CounterVar = nullptr;
+ /// Private loop counter variable.
+ Expr *PrivateCounterVar = nullptr;
+ /// This is initializer for the initial value of #CounterVar.
+ Expr *CounterInit = nullptr;
+ /// This is step for the #CounterVar used to generate its update:
+ /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
+ Expr *CounterStep = nullptr;
+ /// Should step be subtracted?
+ bool Subtract = false;
+ /// Source range of the loop init.
+ SourceRange InitSrcRange;
+ /// Source range of the loop condition.
+ SourceRange CondSrcRange;
+ /// Source range of the loop increment.
+ SourceRange IncSrcRange;
+ /// Minimum value that can have the loop control variable. Used to support
+ /// non-rectangular loops. Applied only for LCV with the non-iterator types,
+ /// since only such variables can be used in non-loop invariant expressions.
+ Expr *MinValue = nullptr;
+ /// Maximum value that can have the loop control variable. Used to support
+ /// non-rectangular loops. Applied only for LCV with the non-iterator type,
+ /// since only such variables can be used in non-loop invariant expressions.
+ Expr *MaxValue = nullptr;
+ /// true, if the lower bound depends on the outer loop control var.
+ bool IsNonRectangularLB = false;
+ /// true, if the upper bound depends on the outer loop control var.
+ bool IsNonRectangularUB = false;
+ /// Index of the loop this loop depends on and forms non-rectangular loop
+ /// nest.
+ unsigned LoopDependentIdx = 0;
+ /// Final condition for the non-rectangular loop nest support. It is used to
+ /// check that the number of iterations for this particular counter must be
+ /// finished.
+ Expr *FinalCondition = nullptr;
+};
+
/// Helper class for checking canonical form of the OpenMP loops and
/// extracting iteration space of each loop in the loop nest, that will be used
/// for IR generation.
@@ -4758,6 +4806,9 @@ class OpenMPIterationSpaceChecker {
Optional<unsigned> CondDependOnLC;
/// Checks if the provide statement depends on the loop counter.
Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
+ /// Original condition required for checking of the exit condition for
+ /// non-rectangular loop.
+ Expr *Condition = nullptr;
public:
OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
@@ -4789,7 +4840,7 @@ public:
bool isStrictTestOp() const { return TestIsStrictOp; }
/// Build the expression to calculate the number of iterations.
Expr *buildNumIterations(
- Scope *S, const bool LimitedType,
+ Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
/// Build the precondition expression for the loops.
Expr *
@@ -4813,8 +4864,21 @@ public:
llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
SourceLocation Loc, Expr *Inc = nullptr,
OverloadedOperatorKind OOK = OO_Amp);
+ /// Builds the minimum value for the loop counter.
+ std::pair<Expr *, Expr *> buildMinMaxValues(
+ Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
+ /// Builds final condition for the non-rectangular loops.
+ Expr *buildFinalCondition(Scope *S) const;
/// Return true if any expression is dependent.
bool dependent() const;
+ /// Returns true if the initializer forms non-rectangular loop.
+ bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
+ /// Returns true if the condition forms non-rectangular loop.
+ bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
+ /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
+ unsigned getLoopDependentIdx() const {
+ return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
+ }
private:
/// Check the right-hand side of an assignment in the increment
@@ -5013,9 +5077,9 @@ public:
return false;
}
bool VisitStmt(const Stmt *S) {
- bool Res = true;
+ bool Res = false;
for (const Stmt *Child : S->children())
- Res = Child && Visit(Child) && Res;
+ Res = (Child && Visit(Child)) || Res;
return Res;
}
explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
@@ -5165,6 +5229,7 @@ bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
return true;
}
+ Condition = S;
S = getExprAsWritten(S);
SourceLocation CondLoc = S->getBeginLoc();
if (auto *BO = dyn_cast<BinaryOperator>(S)) {
@@ -5351,15 +5416,177 @@ tryBuildCapture(Sema &SemaRef, Expr *Capture,
/// Build the expression to calculate the number of iterations.
Expr *OpenMPIterationSpaceChecker::buildNumIterations(
- Scope *S, const bool LimitedType,
+ Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
ExprResult Diff;
QualType VarType = LCDecl->getType().getNonReferenceType();
if (VarType->isIntegerType() || VarType->isPointerType() ||
SemaRef.getLangOpts().CPlusPlus) {
+ Expr *LBVal = LB;
+ Expr *UBVal = UB;
+ // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
+ // max(LB(MinVal), LB(MaxVal))
+ if (InitDependOnLC) {
+ const LoopIterationSpace &IS =
+ ResultIterSpaces[ResultIterSpaces.size() - 1 -
+ InitDependOnLC.getValueOr(
+ CondDependOnLC.getValueOr(0))];
+ if (!IS.MinValue || !IS.MaxValue)
+ return nullptr;
+ // OuterVar = Min
+ ExprResult MinValue =
+ SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
+ if (!MinValue.isUsable())
+ return nullptr;
+
+ ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
+ IS.CounterVar, MinValue.get());
+ if (!LBMinVal.isUsable())
+ return nullptr;
+ // OuterVar = Min, LBVal
+ LBMinVal =
+ SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
+ if (!LBMinVal.isUsable())
+ return nullptr;
+ // (OuterVar = Min, LBVal)
+ LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
+ if (!LBMinVal.isUsable())
+ return nullptr;
+
+ // OuterVar = Max
+ ExprResult MaxValue =
+ SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
+ if (!MaxValue.isUsable())
+ return nullptr;
+
+ ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
+ IS.CounterVar, MaxValue.get());
+ if (!LBMaxVal.isUsable())
+ return nullptr;
+ // OuterVar = Max, LBVal
+ LBMaxVal =
+ SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
+ if (!LBMaxVal.isUsable())
+ return nullptr;
+ // (OuterVar = Max, LBVal)
+ LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
+ if (!LBMaxVal.isUsable())
+ return nullptr;
+
+ Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
+ Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
+ if (!LBMin || !LBMax)
+ return nullptr;
+ // LB(MinVal) < LB(MaxVal)
+ ExprResult MinLessMaxRes =
+ SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
+ if (!MinLessMaxRes.isUsable())
+ return nullptr;
+ Expr *MinLessMax =
+ tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
+ if (!MinLessMax)
+ return nullptr;
+ if (TestIsLessOp.getValue()) {
+ // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
+ // LB(MaxVal))
+ ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
+ MinLessMax, LBMin, LBMax);
+ if (!MinLB.isUsable())
+ return nullptr;
+ LBVal = MinLB.get();
+ } else {
+ // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
+ // LB(MaxVal))
+ ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
+ MinLessMax, LBMax, LBMin);
+ if (!MaxLB.isUsable())
+ return nullptr;
+ LBVal = MaxLB.get();
+ }
+ }
+ // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
+ // min(UB(MinVal), UB(MaxVal))
+ if (CondDependOnLC) {
+ const LoopIterationSpace &IS =
+ ResultIterSpaces[ResultIterSpaces.size() - 1 -
+ InitDependOnLC.getValueOr(
+ CondDependOnLC.getValueOr(0))];
+ if (!IS.MinValue || !IS.MaxValue)
+ return nullptr;
+ // OuterVar = Min
+ ExprResult MinValue =
+ SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
+ if (!MinValue.isUsable())
+ return nullptr;
+
+ ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
+ IS.CounterVar, MinValue.get());
+ if (!UBMinVal.isUsable())
+ return nullptr;
+ // OuterVar = Min, UBVal
+ UBMinVal =
+ SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
+ if (!UBMinVal.isUsable())
+ return nullptr;
+ // (OuterVar = Min, UBVal)
+ UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
+ if (!UBMinVal.isUsable())
+ return nullptr;
+
+ // OuterVar = Max
+ ExprResult MaxValue =
+ SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
+ if (!MaxValue.isUsable())
+ return nullptr;
+
+ ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
+ IS.CounterVar, MaxValue.get());
+ if (!UBMaxVal.isUsable())
+ return nullptr;
+ // OuterVar = Max, UBVal
+ UBMaxVal =
+ SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
+ if (!UBMaxVal.isUsable())
+ return nullptr;
+ // (OuterVar = Max, UBVal)
+ UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
+ if (!UBMaxVal.isUsable())
+ return nullptr;
+
+ Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
+ Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
+ if (!UBMin || !UBMax)
+ return nullptr;
+ // UB(MinVal) > UB(MaxVal)
+ ExprResult MinGreaterMaxRes =
+ SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
+ if (!MinGreaterMaxRes.isUsable())
+ return nullptr;
+ Expr *MinGreaterMax =
+ tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
+ if (!MinGreaterMax)
+ return nullptr;
+ if (TestIsLessOp.getValue()) {
+ // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
+ // UB(MaxVal))
+ ExprResult MaxUB = SemaRef.ActOnConditionalOp(
+ DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
+ if (!MaxUB.isUsable())
+ return nullptr;
+ UBVal = MaxUB.get();
+ } else {
+ // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
+ // UB(MaxVal))
+ ExprResult MinUB = SemaRef.ActOnConditionalOp(
+ DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
+ if (!MinUB.isUsable())
+ return nullptr;
+ UBVal = MinUB.get();
+ }
+ }
// Upper - Lower
- Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
- Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
+ Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
+ Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
if (!Upper || !Lower)
@@ -5446,6 +5673,127 @@ Expr *OpenMPIterationSpaceChecker::buildNumIterations(
return Diff.get();
}
+std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
+ Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
+ // Do not build for iterators, they cannot be used in non-rectangular loop
+ // nests.
+ if (LCDecl->getType()->isRecordType())
+ return std::make_pair(nullptr, nullptr);
+ // If we subtract, the min is in the condition, otherwise the min is in the
+ // init value.
+ Expr *MinExpr = nullptr;
+ Expr *MaxExpr = nullptr;
+ Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
+ Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
+ bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
+ : CondDependOnLC.hasValue();
+ bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
+ : InitDependOnLC.hasValue();
+ Expr *Lower =
+ LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
+ Expr *Upper =
+ UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
+ if (!Upper || !Lower)
+ return std::make_pair(nullptr, nullptr);
+
+ if (TestIsLessOp.getValue())
+ MinExpr = Lower;
+ else
+ MaxExpr = Upper;
+
+ // Build minimum/maximum value based on number of iterations.
+ ExprResult Diff;
+ QualType VarType = LCDecl->getType().getNonReferenceType();
+
+ Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ // Upper - Lower [- 1]
+ if (TestIsStrictOp)
+ Diff = SemaRef.BuildBinOp(
+ S, DefaultLoc, BO_Sub, Diff.get(),
+ SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ // Upper - Lower [- 1] + Step
+ ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
+ if (!NewStep.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ // Parentheses (for dumping/debugging purposes only).
+ Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ // (Upper - Lower [- 1]) / Step
+ Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ // ((Upper - Lower [- 1]) / Step) * Step
+ // Parentheses (for dumping/debugging purposes only).
+ Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ // Convert to the original type or ptrdiff_t, if original type is pointer.
+ if (!VarType->isAnyPointerType() &&
+ !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) {
+ Diff = SemaRef.PerformImplicitConversion(
+ Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true);
+ } else if (VarType->isAnyPointerType() &&
+ !SemaRef.Context.hasSameType(
+ Diff.get()->getType(),
+ SemaRef.Context.getUnsignedPointerDiffType())) {
+ Diff = SemaRef.PerformImplicitConversion(
+ Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
+ Sema::AA_Converting, /*AllowExplicit=*/true);
+ }
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ // Parentheses (for dumping/debugging purposes only).
+ Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+
+ if (TestIsLessOp.getValue()) {
+ // MinExpr = Lower;
+ // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
+ Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get());
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+ Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+ MaxExpr = Diff.get();
+ } else {
+ // MaxExpr = Upper;
+ // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
+ Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+ Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
+ if (!Diff.isUsable())
+ return std::make_pair(nullptr, nullptr);
+ MinExpr = Diff.get();
+ }
+
+ return std::make_pair(MinExpr, MaxExpr);
+}
+
+Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
+ if (InitDependOnLC || CondDependOnLC)
+ return Condition;
+ return nullptr;
+}
+
Expr *OpenMPIterationSpaceChecker::buildPreCond(
Scope *S, Expr *Cond,
llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
@@ -5453,8 +5801,10 @@ Expr *OpenMPIterationSpaceChecker::buildPreCond(
bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
- ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
- ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
+ ExprResult NewLB =
+ InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures);
+ ExprResult NewUB =
+ CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures);
if (!NewLB.isUsable() || !NewUB.isUsable())
return nullptr;
@@ -5576,36 +5926,6 @@ Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
return Diff.get();
}
-
-/// Iteration space of a single for loop.
-struct LoopIterationSpace final {
- /// True if the condition operator is the strict compare operator (<, > or
- /// !=).
- bool IsStrictCompare = false;
- /// Condition of the loop.
- Expr *PreCond = nullptr;
- /// This expression calculates the number of iterations in the loop.
- /// It is always possible to calculate it before starting the loop.
- Expr *NumIterations = nullptr;
- /// The loop counter variable.
- Expr *CounterVar = nullptr;
- /// Private loop counter variable.
- Expr *PrivateCounterVar = nullptr;
- /// This is initializer for the initial value of #CounterVar.
- Expr *CounterInit = nullptr;
- /// This is step for the #CounterVar used to generate its update:
- /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
- Expr *CounterStep = nullptr;
- /// Should step be subtracted?
- bool Subtract = false;
- /// Source range of the loop init.
- SourceRange InitSrcRange;
- /// Source range of the loop condition.
- SourceRange CondSrcRange;
- /// Source range of the loop increment.
- SourceRange IncSrcRange;
-};
-
} // namespace
void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
@@ -5696,7 +6016,7 @@ static bool checkOpenMPIterationSpace(
unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
Expr *OrderedLoopCountExpr,
Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
- LoopIterationSpace &ResultIterSpace,
+ llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
// OpenMP [2.6, Canonical Loop Form]
// for (init-expr; test-expr; incr-expr) structured-block
@@ -5774,37 +6094,57 @@ static bool checkOpenMPIterationSpace(
return HasErrors;
// Build the loop's iteration space representation.
- ResultIterSpace.PreCond =
+ ResultIterSpaces[CurrentNestedLoopCount].PreCond =
ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
- ResultIterSpace.NumIterations = ISC.buildNumIterations(
- DSA.getCurScope(),
- (isOpenMPWorksharingDirective(DKind) ||
- isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
- Captures);
- ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
- ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
- ResultIterSpace.CounterInit = ISC.buildCounterInit();
- ResultIterSpace.CounterStep = ISC.buildCounterStep();
- ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
- ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
- ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
- ResultIterSpace.Subtract = ISC.shouldSubtractStep();
- ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp();
-
- HasErrors |= (ResultIterSpace.PreCond == nullptr ||
- ResultIterSpace.NumIterations == nullptr ||
- ResultIterSpace.CounterVar == nullptr ||
- ResultIterSpace.PrivateCounterVar == nullptr ||
- ResultIterSpace.CounterInit == nullptr ||
- ResultIterSpace.CounterStep == nullptr);
+ ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
+ ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
+ (isOpenMPWorksharingDirective(DKind) ||
+ isOpenMPTaskLoopDirective(DKind) ||
+ isOpenMPDistributeDirective(DKind)),
+ Captures);
+ ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
+ ISC.buildCounterVar(Captures, DSA);
+ ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
+ ISC.buildPrivateCounterVar();
+ ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
+ ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
+ ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
+ ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
+ ISC.getConditionSrcRange();
+ ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
+ ISC.getIncrementSrcRange();
+ ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
+ ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
+ ISC.isStrictTestOp();
+ std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
+ ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
+ ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
+ ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
+ ISC.buildFinalCondition(DSA.getCurScope());
+ ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
+ ISC.doesInitDependOnLC();
+ ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
+ ISC.doesCondDependOnLC();
+ ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
+ ISC.getLoopDependentIdx();
+
+ HasErrors |=
+ (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
+ ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
+ ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
+ ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
+ ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
+ ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
if (!HasErrors && DSA.isOrderedRegion()) {
if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
if (CurrentNestedLoopCount <
DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
DSA.getOrderedRegionParam().second->setLoopNumIterations(
- CurrentNestedLoopCount, ResultIterSpace.NumIterations);
+ CurrentNestedLoopCount,
+ ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
DSA.getOrderedRegionParam().second->setLoopCounter(
- CurrentNestedLoopCount, ResultIterSpace.CounterVar);
+ CurrentNestedLoopCount,
+ ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
}
}
for (auto &Pair : DSA.getDoacrossDependClauses()) {
@@ -5821,11 +6161,13 @@ static bool checkOpenMPIterationSpace(
Expr *CntValue;
if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
CntValue = ISC.buildOrderedLoopData(
- DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
+ DSA.getCurScope(),
+ ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
Pair.first->getDependencyLoc());
else
CntValue = ISC.buildOrderedLoopData(
- DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
+ DSA.getCurScope(),
+ ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
Pair.first->getDependencyLoc(),
Pair.second[CurrentNestedLoopCount].first,
Pair.second[CurrentNestedLoopCount].second);
@@ -5839,10 +6181,12 @@ static bool checkOpenMPIterationSpace(
/// Build 'VarRef = Start.
static ExprResult
buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
- ExprResult Start,
+ ExprResult Start, bool IsNonRectangularLB,
llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
// Build 'VarRef = Start.
- ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
+ ExprResult NewStart = IsNonRectangularLB
+ ? Start.get()
+ : tryBuildCapture(SemaRef, Start.get(), Captures);
if (!NewStart.isUsable())
return ExprError();
if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
@@ -5863,6 +6207,7 @@ buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
static ExprResult buildCounterUpdate(
Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
+ bool IsNonRectangularLB,
llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
// Add parentheses (for debugging purposes only).
Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
@@ -5882,8 +6227,12 @@ static ExprResult buildCounterUpdate(
// Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
// 'VarRef = Start (+|-) Iter * Step'.
- ExprResult NewStart = Start;
- if (Captures)
+ if (!Start.isUsable())
+ return ExprError();
+ ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
+ if (!NewStart.isUsable())
+ return ExprError();
+ if (Captures && !IsNonRectangularLB)
NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
if (NewStart.isInvalid())
return ExprError();
@@ -6054,8 +6403,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
if (checkOpenMPIterationSpace(
DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
- OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
- Captures))
+ OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
return 0;
// Move on to the next nested for loop, or to the loop body.
// OpenMP [2.8.1, simd construct, Restrictions]
@@ -6068,8 +6416,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
if (checkOpenMPIterationSpace(
DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
- OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
- Captures))
+ OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
return 0;
if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
// Handle initialization of captured loop iterator variables.
@@ -6530,6 +6877,9 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
Built.Inits.resize(NestedLoopCount);
Built.Updates.resize(NestedLoopCount);
Built.Finals.resize(NestedLoopCount);
+ Built.DependentCounters.resize(NestedLoopCount);
+ Built.DependentInits.resize(NestedLoopCount);
+ Built.FinalsConditions.resize(NestedLoopCount);
{
// We implement the following algorithm for obtaining the
// original loop iteration variable values based on the
@@ -6589,24 +6939,26 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
DeclRefExpr *CounterVar = buildDeclRefExpr(
SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
/*RefersToCapture=*/true);
- ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
- IS.CounterInit, Captures);
+ ExprResult Init =
+ buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
+ IS.CounterInit, IS.IsNonRectangularLB, Captures);
if (!Init.isUsable()) {
HasErrors = true;
break;
}
ExprResult Update = buildCounterUpdate(
SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
- IS.CounterStep, IS.Subtract, &Captures);
+ IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
if (!Update.isUsable()) {
HasErrors = true;
break;
}
// Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
- ExprResult Final = buildCounterUpdate(
- SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
- IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
+ ExprResult Final =
+ buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
+ IS.CounterInit, IS.NumIterations, IS.CounterStep,
+ IS.Subtract, IS.IsNonRectangularLB, &Captures);
if (!Final.isUsable()) {
HasErrors = true;
break;
@@ -6622,6 +6974,16 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
Built.Inits[Cnt] = Init.get();
Built.Updates[Cnt] = Update.get();
Built.Finals[Cnt] = Final.get();
+ Built.DependentCounters[Cnt] = nullptr;
+ Built.DependentInits[Cnt] = nullptr;
+ Built.FinalsConditions[Cnt] = nullptr;
+ if (IS.IsNonRectangularLB) {
+ Built.DependentCounters[Cnt] =
+ Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
+ Built.DependentInits[Cnt] =
+ Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
+ Built.FinalsConditions[Cnt] = IS.FinalCondition;
+ }
}
}
@@ -6634,7 +6996,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
Built.NumIterations = NumIterations.get();
Built.CalcLastIteration = SemaRef
.ActOnFinishFullExpr(CalcLastIteration.get(),
- /*DiscardedValue*/ false)
+ /*DiscardedValue=*/false)
.get();
Built.PreCond = PreCond.get();
Built.PreInits = buildPreInits(C, Captures);
@@ -12778,9 +13140,9 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
// Build update: Var = InitExpr + IV * Step
ExprResult Update;
if (!Info.first)
- Update =
- buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
- InitExpr, IV, Step, /* Subtract */ false);
+ Update = buildCounterUpdate(
+ SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
+ /*Subtract=*/false, /*IsNonRectangularLB=*/false);
else
Update = *CurPrivate;
Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
@@ -12791,7 +13153,8 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
if (!Info.first)
Final =
buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
- InitExpr, NumIterations, Step, /*Subtract=*/false);
+ InitExpr, NumIterations, Step, /*Subtract=*/false,
+ /*IsNonRectangularLB=*/false);
else
Final = *CurPrivate;
Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index afaaa543bb2..8ab0845d151 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2060,6 +2060,18 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) {
for (unsigned i = 0; i < CollapsedNum; ++i)
Sub.push_back(Record.readSubExpr());
D->setFinals(Sub);
+ Sub.clear();
+ for (unsigned i = 0; i < CollapsedNum; ++i)
+ Sub.push_back(Record.readSubExpr());
+ D->setDependentCounters(Sub);
+ Sub.clear();
+ for (unsigned i = 0; i < CollapsedNum; ++i)
+ Sub.push_back(Record.readSubExpr());
+ D->setDependentInits(Sub);
+ Sub.clear();
+ for (unsigned i = 0; i < CollapsedNum; ++i)
+ Sub.push_back(Record.readSubExpr());
+ D->setFinalsConditions(Sub);
}
void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) {
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 4fbcbaabe74..a6927f32c0e 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1995,6 +1995,12 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
for (auto I : D->finals()) {
Record.AddStmt(I);
}
+ for (Stmt *S : D->dependent_counters())
+ Record.AddStmt(S);
+ for (Stmt *S : D->dependent_inits())
+ Record.AddStmt(S);
+ for (Stmt *S : D->finals_conditions())
+ Record.AddStmt(S);
}
void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
OpenPOWER on IntegriCloud