summaryrefslogtreecommitdiffstats
path: root/polly/lib/Analysis/ScopDetection.cpp
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2016-03-01 21:44:06 +0000
committerMichael Kruse <llvm@meinersbur.de>2016-03-01 21:44:06 +0000
commitc7e0d9c216d552456f78be3fc94f077d009bdb1f (patch)
treec0bf333b9af3657582b2c3e653b7f0b097e51077 /polly/lib/Analysis/ScopDetection.cpp
parent89244ba84a6f2f3095cb77fbf9e78dd9b04fbe1d (diff)
downloadbcm5719-llvm-c7e0d9c216d552456f78be3fc94f077d009bdb1f.tar.gz
bcm5719-llvm-c7e0d9c216d552456f78be3fc94f077d009bdb1f.zip
Fix non-synthesizable loop exit values.
Polly recognizes affine loops that ScalarEvolution does not, in particular those with loop conditions that depend on hoisted invariant loads. Check for SCEVAddRec dependencies on such loops and do not consider their exit values as synthesizable because SCEVExpander would generate them as expressions that depend on the original induction variables. These are not available in generated code. llvm-svn: 262404
Diffstat (limited to 'polly/lib/Analysis/ScopDetection.cpp')
-rw-r--r--polly/lib/Analysis/ScopDetection.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index 4776a7f2ab8..47bf54786fb 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -716,7 +716,8 @@ ScopDetection::getDelinearizationTerms(DetectionContext &Context,
bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
SmallVectorImpl<const SCEV *> &Sizes,
- const SCEVUnknown *BasePointer) const {
+ const SCEVUnknown *BasePointer,
+ Loop *Scope) const {
Value *BaseValue = BasePointer->getValue();
Region &CurRegion = Context.CurRegion;
for (const SCEV *DelinearizedSize : Sizes) {
@@ -733,7 +734,7 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
continue;
}
}
- if (hasScalarDepsInsideRegion(DelinearizedSize, &CurRegion))
+ if (hasScalarDepsInsideRegion(DelinearizedSize, &CurRegion, Scope, false))
return invalid<ReportNonAffineAccess>(
Context, /*Assert=*/true, DelinearizedSize,
Context.Accesses[BasePointer].front().first, BaseValue);
@@ -813,8 +814,9 @@ bool ScopDetection::computeAccessFunctions(
return true;
}
-bool ScopDetection::hasBaseAffineAccesses(
- DetectionContext &Context, const SCEVUnknown *BasePointer) const {
+bool ScopDetection::hasBaseAffineAccesses(DetectionContext &Context,
+ const SCEVUnknown *BasePointer,
+ Loop *Scope) const {
auto Shape = std::shared_ptr<ArrayShape>(new ArrayShape(BasePointer));
auto Terms = getDelinearizationTerms(Context, BasePointer);
@@ -822,7 +824,8 @@ bool ScopDetection::hasBaseAffineAccesses(
SE->findArrayDimensions(Terms, Shape->DelinearizedSizes,
Context.ElementSize[BasePointer]);
- if (!hasValidArraySizes(Context, Shape->DelinearizedSizes, BasePointer))
+ if (!hasValidArraySizes(Context, Shape->DelinearizedSizes, BasePointer,
+ Scope))
return false;
return computeAccessFunctions(Context, BasePointer, Shape);
@@ -834,13 +837,16 @@ bool ScopDetection::hasAffineMemoryAccesses(DetectionContext &Context) const {
if (Context.HasUnknownAccess && !Context.NonAffineAccesses.empty())
return AllowNonAffine;
- for (const SCEVUnknown *BasePointer : Context.NonAffineAccesses)
- if (!hasBaseAffineAccesses(Context, BasePointer)) {
+ for (auto &Pair : Context.NonAffineAccesses) {
+ auto *BasePointer = Pair.first;
+ auto *Scope = Pair.second;
+ if (!hasBaseAffineAccesses(Context, BasePointer, Scope)) {
if (KeepGoing)
continue;
else
return false;
}
+ }
return true;
}
@@ -901,7 +907,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
Context.Accesses[BP].push_back({Inst, AF});
if (!IsAffine)
- Context.NonAffineAccesses.insert(BP);
+ Context.NonAffineAccesses.insert(
+ std::make_pair(BP, LI->getLoopFor(Inst->getParent())));
} else if (!AllowNonAffine && !IsAffine) {
return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Inst,
BV);
OpenPOWER on IntegriCloud