r359132 - [OPENMP]Initial support for non-rectangular loop nest.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 24 12:58:30 PDT 2019
Author: abataev
Date: Wed Apr 24 12:58:30 2019
New Revision: 359132
URL: http://llvm.org/viewvc/llvm-project?rev=359132&view=rev
Log:
[OPENMP]Initial support for non-rectangular loop nest.
Added basic semantic analysis for the non-rectangular loop nests for
OpenMP 5.0 support.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/test/OpenMP/for_loop_messages.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=359132&r1=359131&r2=359132&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr 24 12:58:30 2019
@@ -9170,6 +9170,8 @@ def warn_omp_allocate_thread_on_task_tar
InGroup<OpenMPClauses>;
def err_omp_expected_private_copy_for_allocate : Error<
"the referenced item is not found in any private clause on the same directive">;
+def err_omp_stmt_depends_on_loop_counter : Error<
+ "the loop %select{initializer|condition}0 expression depends on the current loop control variable">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=359132&r1=359131&r2=359132&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Apr 24 12:58:30 2019
@@ -4487,6 +4487,8 @@ namespace {
class OpenMPIterationSpaceChecker {
/// Reference to Sema.
Sema &SemaRef;
+ /// Data-sharing stack.
+ DSAStackTy &Stack;
/// A location for diagnostics (when there is no some better location).
SourceLocation DefaultLoc;
/// A location for diagnostics (when increment is not compatible).
@@ -4518,10 +4520,14 @@ class OpenMPIterationSpaceChecker {
bool TestIsStrictOp = false;
/// This flag is true when step is subtracted on each iteration.
bool SubtractStep = false;
+ /// Checks if the provide statement depends on the loop counter.
+ bool doesDependOnLoopCounter(const Stmt *S, bool IsInitializer) const;
public:
- OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
- : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
+ OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
+ SourceLocation DefaultLoc)
+ : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
+ ConditionLoc(DefaultLoc) {}
/// Check init-expr for canonical loop form and save loop counter
/// variable - #Var and its initialization value - #LB.
bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
@@ -4579,7 +4585,8 @@ private:
/// expression.
bool checkAndSetIncRHS(Expr *RHS);
/// Helper to set loop counter variable and its initializer.
- bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
+ bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
+ bool EmitDiags);
/// Helper to set upper bound.
bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
SourceRange SR, SourceLocation SL);
@@ -4599,7 +4606,7 @@ bool OpenMPIterationSpaceChecker::depend
bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
Expr *NewLCRefExpr,
- Expr *NewLB) {
+ Expr *NewLB, bool EmitDiags) {
// State consistency checking to ensure correct usage.
assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
@@ -4614,6 +4621,8 @@ bool OpenMPIterationSpaceChecker::setLCD
CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
NewLB = CE->getArg(0)->IgnoreParenImpCasts();
LB = NewLB;
+ if (EmitDiags)
+ (void)doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
return false;
}
@@ -4632,6 +4641,7 @@ bool OpenMPIterationSpaceChecker::setUB(
TestIsStrictOp = StrictOp;
ConditionSrcRange = SR;
ConditionLoc = SL;
+ (void)doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
return false;
}
@@ -4697,6 +4707,66 @@ bool OpenMPIterationSpaceChecker::setSte
return false;
}
+namespace {
+/// Checker for the non-rectangular loops. Checks if the initializer or
+/// condition expression references loop counter variable.
+class LoopCounterRefChecker final
+ : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
+ Sema &SemaRef;
+ DSAStackTy &Stack;
+ const ValueDecl *CurLCDecl = nullptr;
+ bool IsInitializer = true;
+
+public:
+ bool VisitDeclRefExpr(const DeclRefExpr *E) {
+ const ValueDecl *VD = E->getDecl();
+ if (isa<VarDecl>(VD)) {
+ if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
+ SemaRef.Diag(E->getExprLoc(),
+ diag::err_omp_stmt_depends_on_loop_counter)
+ << (IsInitializer ? 0 : 1);
+ return false;
+ }
+ const auto &&Data = Stack.isLoopControlVariable(VD);
+ return Data.first;
+ }
+ return false;
+ }
+ bool VisitMemberExpr(const MemberExpr *E) {
+ if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
+ const ValueDecl *VD = E->getMemberDecl();
+ if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
+ SemaRef.Diag(E->getExprLoc(),
+ diag::err_omp_stmt_depends_on_loop_counter)
+ << (IsInitializer ? 0 : 1);
+ return false;
+ }
+ const auto &&Data = Stack.isLoopControlVariable(VD);
+ return Data.first;
+ }
+ return false;
+ }
+ bool VisitStmt(const Stmt *S) {
+ for (const Stmt *Child : S->children()) {
+ if (Child && Visit(Child))
+ return true;
+ }
+ return false;
+ }
+ explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
+ const ValueDecl *CurLCDecl, bool IsInitializer)
+ : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
+ IsInitializer(IsInitializer) {}
+};
+} // namespace
+
+bool OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
+ const Stmt *S, bool IsInitializer) const {
+ // Check for the non-rectangular loops.
+ LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer);
+ return LoopStmtChecker.Visit(S);
+}
+
bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
// Check init-expr for canonical loop form and save loop counter
// variable - #Var and its initialization value - #LB.
@@ -4725,13 +4795,15 @@ bool OpenMPIterationSpaceChecker::checkA
if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
- return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
- return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
+ return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
+ EmitDiags);
+ return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
}
if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
if (ME->isArrow() &&
isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
- return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
+ return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
+ EmitDiags);
}
}
} else if (auto *DS = dyn_cast<DeclStmt>(S)) {
@@ -4748,7 +4820,7 @@ bool OpenMPIterationSpaceChecker::checkA
buildDeclRefExpr(SemaRef, Var,
Var->getType().getNonReferenceType(),
DS->getBeginLoc()),
- Var->getInit());
+ Var->getInit(), EmitDiags);
}
}
}
@@ -4758,13 +4830,15 @@ bool OpenMPIterationSpaceChecker::checkA
if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
- return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
- return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
+ return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
+ EmitDiags);
+ return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
}
if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
if (ME->isArrow() &&
isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
- return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
+ return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
+ EmitDiags);
}
}
}
@@ -5261,7 +5335,7 @@ void Sema::ActOnOpenMPLoopInitialization
if (AssociatedLoops > 0 &&
isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
DSAStack->loopStart();
- OpenMPIterationSpaceChecker ISC(*this, ForLoc);
+ OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
if (ValueDecl *D = ISC.getLoopDecl()) {
auto *VD = dyn_cast<VarDecl>(D);
@@ -5327,7 +5401,7 @@ static bool checkOpenMPIterationSpace(
}
assert(For->getBody());
- OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
+ OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc());
// Check init.
Stmt *Init = For->getInit();
Modified: cfe/trunk/test/OpenMP/for_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_loop_messages.cpp?rev=359132&r1=359131&r2=359132&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/for_loop_messages.cpp Wed Apr 24 12:58:30 2019
@@ -287,6 +287,13 @@ int test_iteration_spaces() {
c[ii] = a[ii];
#pragma omp parallel
+// expected-error at +3 {{the loop initializer expression depends on the current loop control variable}}
+// expected-error at +2 2 {{the loop condition expression depends on the current loop control variable}}
+#pragma omp for
+ for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1)
+ c[ii] = a[ii];
+
+#pragma omp parallel
// expected-note at +2 {{defined as firstprivate}}
// expected-error at +2 {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}}
#pragma omp for firstprivate(ii)
@@ -596,9 +603,17 @@ int test_with_random_access_iterator() {
template <typename IT, int ST>
class TC {
+ int ii;
public:
int dotest_lt(IT begin, IT end) {
#pragma omp parallel
+// expected-error at +3 3 {{the loop initializer expression depends on the current loop control variable}}
+// expected-error at +2 6 {{the loop condition expression depends on the current loop control variable}}
+#pragma omp for
+ for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1)
+ ;
+
+#pragma omp parallel
// expected-note at +3 {{loop step is expected to be positive due to this condition}}
// expected-error at +2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
#pragma omp for
@@ -659,7 +674,7 @@ void test_with_template() {
GoodIter begin, end;
TC<GoodIter, 100> t1;
TC<GoodIter, -100> t2;
- t1.dotest_lt(begin, end);
+ t1.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, 100>::dotest_lt' requested here}}
t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
dotest_gt<unsigned, 10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, 10>' requested here}}
More information about the cfe-commits
mailing list