delinearize memory access functions
llvm-svn: 205799
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index 69c63ae..5f03e7a 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -117,6 +117,12 @@
cl::location(PollyTrackFailures), cl::Hidden, cl::ZeroOrMore,
cl::init(false), cl::cat(PollyCategory));
+static cl::opt<bool, true>
+PollyDelinearizeX("polly-delinearize",
+ cl::desc("Delinearize array access functions"),
+ cl::location(PollyDelinearize), cl::Hidden, cl::ZeroOrMore,
+ cl::init(false), cl::cat(PollyCategory));
+
static cl::opt<bool>
VerifyScops("polly-detect-verify",
cl::desc("Verify the detected SCoPs after each transformation"),
@@ -124,6 +130,7 @@
cl::cat(PollyCategory));
bool polly::PollyTrackFailures = false;
+bool polly::PollyDelinearize = false;
//===----------------------------------------------------------------------===//
// Statistics.
@@ -357,11 +364,25 @@
return invalid<ReportVariantBasePtr>(Context, /*Assert=*/false, BaseValue);
AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
+ const SCEVAddRecExpr *AF = dyn_cast<SCEVAddRecExpr>(AccessFunction);
- if (!AllowNonAffine &&
- !isAffineExpr(&Context.CurRegion, AccessFunction, *SE, BaseValue))
+ if (AllowNonAffine) {
+ // Do not check whether AccessFunction is affine.
+ } else if (PollyDelinearize && AF) {
+ // Try to delinearize AccessFunction.
+ SmallVector<const SCEV *, 4> Subscripts, Sizes;
+ AF->delinearize(*SE, Subscripts, Sizes);
+ int size = Subscripts.size();
+
+ for (int i = 0; i < size; ++i)
+ if (!isAffineExpr(&Context.CurRegion, Subscripts[i], *SE, BaseValue))
+ return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true,
+ AccessFunction);
+ } else if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE,
+ BaseValue)) {
return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true,
AccessFunction);
+ }
// FIXME: Alias Analysis thinks IntToPtrInst aliases with alloca instructions
// created by IndependentBlocks Pass.