diff options
Diffstat (limited to 'polly/lib')
-rw-r--r-- | polly/lib/Analysis/ScopBuilder.cpp | 7 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopDetection.cpp | 23 | ||||
-rw-r--r-- | polly/lib/Support/SCEVValidator.cpp | 35 |
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); |