summaryrefslogtreecommitdiffstats
path: root/polly/lib
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib')
-rw-r--r--polly/lib/Analysis/ScopBuilder.cpp7
-rw-r--r--polly/lib/Analysis/ScopDetection.cpp23
-rw-r--r--polly/lib/Support/SCEVValidator.cpp35
3 files changed, 60 insertions, 5 deletions
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 83396809fe2..f3623525df4 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -407,6 +407,13 @@ bool ScopBuilder::buildAccessMultiDimParam(MemAccInst Inst, ScopStmt *Stmt) {
Sizes.insert(Sizes.end(), AccItr->second.Shape->DelinearizedSizes.begin(),
AccItr->second.Shape->DelinearizedSizes.end());
+
+ // In case only the element size is contained in the 'Sizes' array, the
+ // access does not access a real multi-dimensional array. Hence, we allow
+ // the normal single-dimensional access construction to handle this.
+ if (Sizes.size() == 1)
+ return false;
+
// Remove the element size. This information is already provided by the
// ElementSize parameter. In case the element size of this access and the
// element size used for delinearization differs the delinearization is
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index d1d6360ab44..d5c154fa08a 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -823,6 +823,15 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
SmallVectorImpl<const SCEV *> &Sizes,
const SCEVUnknown *BasePointer,
Loop *Scope) const {
+ // If no sizes were found, all sizes are trivially valid. We allow this case
+ // to make it possible to pass known-affine accesses to the delinearization to
+ // try to recover some interesting multi-dimensional accesses, but to still
+ // allow the already known to be affine access in case the delinearization
+ // fails. In such situations, the delinearization will just return a Sizes
+ // array of size zero.
+ if (Sizes.size() == 0)
+ return true;
+
Value *BaseValue = BasePointer->getValue();
Region &CurRegion = Context.CurRegion;
for (const SCEV *DelinearizedSize : Sizes) {
@@ -893,10 +902,14 @@ bool ScopDetection::computeAccessFunctions(
else
IsNonAffine = true;
} else {
- SE.computeAccessFunctions(AF, Acc->DelinearizedSubscripts,
- Shape->DelinearizedSizes);
- if (Acc->DelinearizedSubscripts.size() == 0)
- IsNonAffine = true;
+ if (Shape->DelinearizedSizes.size() == 0) {
+ Acc->DelinearizedSubscripts.push_back(AF);
+ } else {
+ SE.computeAccessFunctions(AF, Acc->DelinearizedSubscripts,
+ Shape->DelinearizedSizes);
+ if (Acc->DelinearizedSubscripts.size() == 0)
+ IsNonAffine = true;
+ }
for (const SCEV *S : Acc->DelinearizedSubscripts)
if (!isAffine(S, Scope, Context))
IsNonAffine = true;
@@ -1013,7 +1026,7 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
} else if (PollyDelinearize && !IsVariantInNonAffineLoop) {
Context.Accesses[BP].push_back({Inst, AF});
- if (!IsAffine)
+ if (!IsAffine || hasIVParams(AF))
Context.NonAffineAccesses.insert(
std::make_pair(BP, LI.getLoopFor(Inst->getParent())));
} else if (!AllowNonAffine && !IsAffine) {
diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp
index 0e159f42993..1941875d0d5 100644
--- a/polly/lib/Support/SCEVValidator.cpp
+++ b/polly/lib/Support/SCEVValidator.cpp
@@ -429,6 +429,34 @@ public:
}
};
+class SCEVHasIVParams {
+ bool HasIVParams = false;
+
+public:
+ SCEVHasIVParams() {}
+
+ bool follow(const SCEV *S) {
+ const SCEVUnknown *Unknown = dyn_cast<SCEVUnknown>(S);
+ if (!Unknown)
+ return true;
+
+ CallInst *Call = dyn_cast<CallInst>(Unknown->getValue());
+
+ if (!Call)
+ return true;
+
+ if (isConstCall(Call)) {
+ HasIVParams = true;
+ return false;
+ }
+
+ return true;
+ }
+
+ bool isDone() { return HasIVParams; }
+ bool hasIVParams() { return HasIVParams; }
+};
+
/// Check whether a SCEV refers to an SSA name defined inside a region.
class SCEVInRegionDependences {
const Region *R;
@@ -542,6 +570,13 @@ void findValues(const SCEV *Expr, ScalarEvolution &SE,
ST.visitAll(Expr);
}
+bool hasIVParams(const SCEV *Expr) {
+ SCEVHasIVParams HasIVParams;
+ SCEVTraversal<SCEVHasIVParams> ST(HasIVParams);
+ ST.visitAll(Expr);
+ return HasIVParams.hasIVParams();
+}
+
bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R,
llvm::Loop *Scope, bool AllowLoops) {
SCEVInRegionDependences InRegionDeps(R, Scope, AllowLoops);
OpenPOWER on IntegriCloud