[polly] r208457 - delinearize together all accesses to the same array
Sebastian Pop
spop at codeaurora.org
Fri May 9 15:45:16 PDT 2014
Author: spop
Date: Fri May 9 17:45:15 2014
New Revision: 208457
URL: http://llvm.org/viewvc/llvm-project?rev=208457&view=rev
Log:
delinearize together all accesses to the same array
Modified:
polly/trunk/include/polly/ScopDetection.h
polly/trunk/lib/Analysis/ScopDetection.cpp
Modified: polly/trunk/include/polly/ScopDetection.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopDetection.h?rev=208457&r1=208456&r2=208457&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopDetection.h (original)
+++ polly/trunk/include/polly/ScopDetection.h Fri May 9 17:45:15 2014
@@ -63,6 +63,7 @@ class Loop;
class ScalarEvolution;
class SCEV;
class SCEVAddRecExpr;
+class SCEVUnknown;
class CallInst;
class Instruction;
class AliasAnalysis;
@@ -72,6 +73,9 @@ class Value;
namespace polly {
typedef std::set<const SCEV *> ParamSetType;
+typedef std::vector<const SCEVAddRecExpr *> AFs;
+typedef std::map<const SCEVUnknown *, AFs> BaseToAFs;
+
extern bool PollyTrackFailures;
extern bool PollyDelinearize;
@@ -96,6 +100,10 @@ class ScopDetection : public FunctionPas
Region &CurRegion; // The region to check.
AliasSetTracker AST; // The AliasSetTracker to hold the alias information.
bool Verifying; // If we are in the verification phase?
+
+ // Map a base pointer to all access functions accessing it.
+ BaseToAFs NonAffineAccesses;
+
DetectionContext(Region &R, AliasAnalysis &AA, bool Verify)
: CurRegion(R), AST(AA), Verifying(Verify) {}
};
@@ -112,6 +120,11 @@ class ScopDetection : public FunctionPas
FunctionSet InvalidFunctions;
mutable std::string LastFailure;
+ // Delinearize all non affine memory accesses and return true when there
+ // exists a non affine memory access that cannot be delinearized. Return
+ // false when all array accesses are affine after delinearization.
+ bool hasNonAffineMemoryAccesses(DetectionContext &Context) const;
+
// Try to expand the region R. If R can be expanded return the expanded
// region, NULL otherwise.
Region *expandRegion(Region &R);
Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=208457&r1=208456&r2=208457&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Fri May 9 17:45:15 2014
@@ -337,6 +337,35 @@ bool ScopDetection::isInvariant(const Va
return true;
}
+bool
+ScopDetection::hasNonAffineMemoryAccesses(DetectionContext &Context) const {
+ for (auto P : Context.NonAffineAccesses) {
+ const SCEVUnknown *BasePointer = P.first;
+ Value *BaseValue = BasePointer->getValue();
+
+ // First step: collect parametric terms in all array references.
+ SmallVector<const SCEV *, 4> Terms;
+ for (const SCEVAddRecExpr *AF : Context.NonAffineAccesses[BasePointer])
+ AF->collectParametricTerms(*SE, Terms);
+
+ // Second step: find array shape.
+ SmallVector<const SCEV *, 4> Sizes;
+ SE->findArrayDimensions(Terms, Sizes);
+
+ // Third step: compute the access functions for each subscript.
+ for (const SCEVAddRecExpr *AF : Context.NonAffineAccesses[BasePointer]) {
+ SmallVector<const SCEV *, 4> Subscripts;
+ AF->computeAccessFunctions(*SE, Subscripts, Sizes);
+
+ // Check that the delinearized subscripts are affine.
+ for (const SCEV *S : Subscripts)
+ if (!isAffineExpr(&Context.CurRegion, S, *SE, BaseValue))
+ return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF);
+ }
+ }
+ return false;
+}
+
bool ScopDetection::isValidMemoryAccess(Instruction &Inst,
DetectionContext &Context) const {
Value *Ptr = getPointerOperand(Inst);
@@ -370,21 +399,17 @@ bool ScopDetection::isValidMemoryAccess(
} else if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE,
BaseValue)) {
const SCEVAddRecExpr *AF = dyn_cast<SCEVAddRecExpr>(AccessFunction);
+
if (!PollyDelinearize || !AF)
return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true,
AccessFunction);
- // Try to delinearize AccessFunction only when the expression is known to
- // not be affine: as all affine functions can be represented without
- // problems in Polly, we do not have to delinearize them.
- 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);
+ // Collect all non affine memory accesses, and check whether they are linear
+ // at the end of scop detection. That way we can delinearize all the memory
+ // accesses to the same array in a unique step.
+ if (Context.NonAffineAccesses[BasePointer].size() == 0)
+ Context.NonAffineAccesses[BasePointer] = AFs();
+ Context.NonAffineAccesses[BasePointer].push_back(AF);
}
// FIXME: Alias Analysis thinks IntToPtrInst aliases with alloca instructions
@@ -609,6 +634,9 @@ bool ScopDetection::allBlocksValid(Detec
if (!isValidInstruction(*I, Context))
return false;
+ if (hasNonAffineMemoryAccesses(Context))
+ return false;
+
return true;
}
More information about the llvm-commits
mailing list