@@ -4520,8 +4520,16 @@ class OpenMPIterationSpaceChecker {
4520
4520
bool TestIsStrictOp = false;
4521
4521
/// This flag is true when step is subtracted on each iteration.
4522
4522
bool SubtractStep = false;
4523
+ /// The outer loop counter this loop depends on (if any).
4524
+ const ValueDecl *DepDecl = nullptr;
4525
+ /// Contains number of loop (starts from 1) on which loop counter init
4526
+ /// expression of this loop depends on.
4527
+ Optional<unsigned> InitDependOnLC;
4528
+ /// Contains number of loop (starts from 1) on which loop counter condition
4529
+ /// expression of this loop depends on.
4530
+ Optional<unsigned> CondDependOnLC;
4523
4531
/// Checks if the provide statement depends on the loop counter.
4524
- bool doesDependOnLoopCounter(const Stmt *S, bool IsInitializer) const ;
4532
+ Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
4525
4533
4526
4534
public:
4527
4535
OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
@@ -4622,7 +4630,7 @@ bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
4622
4630
NewLB = CE->getArg(0)->IgnoreParenImpCasts();
4623
4631
LB = NewLB;
4624
4632
if (EmitDiags)
4625
- (void) doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
4633
+ InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
4626
4634
return false;
4627
4635
}
4628
4636
@@ -4641,7 +4649,7 @@ bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
4641
4649
TestIsStrictOp = StrictOp;
4642
4650
ConditionSrcRange = SR;
4643
4651
ConditionLoc = SL;
4644
- (void) doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
4652
+ CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
4645
4653
return false;
4646
4654
}
4647
4655
@@ -4716,58 +4724,62 @@ class LoopCounterRefChecker final
4716
4724
DSAStackTy &Stack;
4717
4725
const ValueDecl *CurLCDecl = nullptr;
4718
4726
const ValueDecl *DepDecl = nullptr;
4727
+ const ValueDecl *PrevDepDecl = nullptr;
4719
4728
bool IsInitializer = true;
4729
+ unsigned BaseLoopId = 0;
4730
+ bool checkDecl(const Expr *E, const ValueDecl *VD) {
4731
+ if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
4732
+ SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
4733
+ << (IsInitializer ? 0 : 1);
4734
+ return false;
4735
+ }
4736
+ const auto &&Data = Stack.isLoopControlVariable(VD);
4737
+ // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
4738
+ // The type of the loop iterator on which we depend may not have a random
4739
+ // access iterator type.
4740
+ if (Data.first && VD->getType()->isRecordType()) {
4741
+ SmallString<128> Name;
4742
+ llvm::raw_svector_ostream OS(Name);
4743
+ VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
4744
+ /*Qualified=*/true);
4745
+ SemaRef.Diag(E->getExprLoc(),
4746
+ diag::err_omp_wrong_dependency_iterator_type)
4747
+ << OS.str();
4748
+ SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
4749
+ return false;
4750
+ }
4751
+ if (Data.first &&
4752
+ (DepDecl || (PrevDepDecl &&
4753
+ getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
4754
+ if (!DepDecl && PrevDepDecl)
4755
+ DepDecl = PrevDepDecl;
4756
+ SmallString<128> Name;
4757
+ llvm::raw_svector_ostream OS(Name);
4758
+ DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
4759
+ /*Qualified=*/true);
4760
+ SemaRef.Diag(E->getExprLoc(),
4761
+ diag::err_omp_invariant_or_linear_dependency)
4762
+ << OS.str();
4763
+ return false;
4764
+ }
4765
+ if (Data.first) {
4766
+ DepDecl = VD;
4767
+ BaseLoopId = Data.first;
4768
+ }
4769
+ return Data.first;
4770
+ }
4720
4771
4721
4772
public:
4722
4773
bool VisitDeclRefExpr(const DeclRefExpr *E) {
4723
4774
const ValueDecl *VD = E->getDecl();
4724
- if (isa<VarDecl>(VD)) {
4725
- if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
4726
- SemaRef.Diag(E->getExprLoc(),
4727
- diag::err_omp_stmt_depends_on_loop_counter)
4728
- << (IsInitializer ? 0 : 1);
4729
- return false;
4730
- }
4731
- const auto &&Data = Stack.isLoopControlVariable(VD);
4732
- if (DepDecl && Data.first) {
4733
- SmallString<128> Name;
4734
- llvm::raw_svector_ostream OS(Name);
4735
- DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
4736
- /*Qualified=*/true);
4737
- SemaRef.Diag(E->getExprLoc(),
4738
- diag::err_omp_invariant_or_linear_dependancy)
4739
- << OS.str();
4740
- return false;
4741
- }
4742
- if (Data.first)
4743
- DepDecl = VD;
4744
- return Data.first;
4745
- }
4775
+ if (isa<VarDecl>(VD))
4776
+ return checkDecl(E, VD);
4746
4777
return false;
4747
4778
}
4748
4779
bool VisitMemberExpr(const MemberExpr *E) {
4749
4780
if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
4750
4781
const ValueDecl *VD = E->getMemberDecl();
4751
- if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
4752
- SemaRef.Diag(E->getExprLoc(),
4753
- diag::err_omp_stmt_depends_on_loop_counter)
4754
- << (IsInitializer ? 0 : 1);
4755
- return false;
4756
- }
4757
- const auto &&Data = Stack.isLoopControlVariable(VD);
4758
- if (DepDecl && Data.first) {
4759
- SmallString<128> Name;
4760
- llvm::raw_svector_ostream OS(Name);
4761
- DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
4762
- /*Qualified=*/true);
4763
- SemaRef.Diag(E->getExprLoc(),
4764
- diag::err_omp_invariant_or_linear_dependancy)
4765
- << OS.str();
4766
- return false;
4767
- }
4768
- if (Data.first)
4769
- DepDecl = VD;
4770
- return Data.first;
4782
+ return checkDecl(E, VD);
4771
4783
}
4772
4784
return false;
4773
4785
}
@@ -4778,17 +4790,32 @@ class LoopCounterRefChecker final
4778
4790
return Res;
4779
4791
}
4780
4792
explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
4781
- const ValueDecl *CurLCDecl, bool IsInitializer)
4793
+ const ValueDecl *CurLCDecl, bool IsInitializer,
4794
+ const ValueDecl *PrevDepDecl = nullptr)
4782
4795
: SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
4783
- IsInitializer(IsInitializer) {}
4796
+ PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
4797
+ unsigned getBaseLoopId() const {
4798
+ assert(CurLCDecl && "Expected loop dependency.");
4799
+ return BaseLoopId;
4800
+ }
4801
+ const ValueDecl *getDepDecl() const {
4802
+ assert(CurLCDecl && "Expected loop dependency.");
4803
+ return DepDecl;
4804
+ }
4784
4805
};
4785
4806
} // namespace
4786
4807
4787
- bool OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
4788
- const Stmt *S, bool IsInitializer) const {
4808
+ Optional<unsigned>
4809
+ OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
4810
+ bool IsInitializer) {
4789
4811
// Check for the non-rectangular loops.
4790
- LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer);
4791
- return LoopStmtChecker.Visit(S);
4812
+ LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
4813
+ DepDecl);
4814
+ if (LoopStmtChecker.Visit(S)) {
4815
+ DepDecl = LoopStmtChecker.getDepDecl();
4816
+ return LoopStmtChecker.getBaseLoopId();
4817
+ }
4818
+ return llvm::None;
4792
4819
}
4793
4820
4794
4821
bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
0 commit comments