Move delinearization from SCEVAddRecExpr to ScalarEvolution

The expressions we delinearize do not necessarily have to have a SCEVAddRecExpr
at the outermost level. At this moment, the additional flexibility  is not
exploited in LLVM itself, but in Polly we will soon soonish use this
functionality. For LLVM, this change should not affect existing functionality
(which is covered by test/Analysis/Delinearization/)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240952 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tobias Grosser
2015-06-29 14:42:48 +00:00
parent 9a6c902332
commit 032d56baf2
5 changed files with 105 additions and 99 deletions
+20 -16
View File
@@ -7647,11 +7647,11 @@ struct SCEVCollectTerms {
}
/// Find parametric terms in this SCEVAddRecExpr.
void SCEVAddRecExpr::collectParametricTerms(
ScalarEvolution &SE, SmallVectorImpl<const SCEV *> &Terms) const {
void ScalarEvolution::collectParametricTerms(const SCEV *Expr,
SmallVectorImpl<const SCEV *> &Terms) {
SmallVector<const SCEV *, 4> Strides;
SCEVCollectStrides StrideCollector(SE, Strides);
visitAll(this, StrideCollector);
SCEVCollectStrides StrideCollector(*this, Strides);
visitAll(Expr, StrideCollector);
DEBUG({
dbgs() << "Strides:\n";
@@ -7867,19 +7867,23 @@ void ScalarEvolution::findArrayDimensions(SmallVectorImpl<const SCEV *> &Terms,
/// Third step of delinearization: compute the access functions for the
/// Subscripts based on the dimensions in Sizes.
void SCEVAddRecExpr::computeAccessFunctions(
ScalarEvolution &SE, SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes) const {
void ScalarEvolution::computeAccessFunctions(
const SCEV *Expr, SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes) {
// Early exit in case this SCEV is not an affine multivariate function.
if (Sizes.empty() || !this->isAffine())
if (Sizes.empty())
return;
const SCEV *Res = this;
if (auto AR = dyn_cast<SCEVAddRecExpr>(Expr))
if (!AR->isAffine())
return;
const SCEV *Res = Expr;
int Last = Sizes.size() - 1;
for (int i = Last; i >= 0; i--) {
const SCEV *Q, *R;
SCEVDivision::divide(SE, Res, Sizes[i], &Q, &R);
SCEVDivision::divide(*this, Res, Sizes[i], &Q, &R);
DEBUG({
dbgs() << "Res: " << *Res << "\n";
@@ -7971,31 +7975,31 @@ void SCEVAddRecExpr::computeAccessFunctions(
/// asking for the SCEV of the memory access with respect to all enclosing
/// loops, calling SCEV->delinearize on that and printing the results.
void SCEVAddRecExpr::delinearize(ScalarEvolution &SE,
void ScalarEvolution::delinearize(const SCEV *Expr,
SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes,
const SCEV *ElementSize) const {
const SCEV *ElementSize) {
// First step: collect parametric terms.
SmallVector<const SCEV *, 4> Terms;
collectParametricTerms(SE, Terms);
collectParametricTerms(Expr, Terms);
if (Terms.empty())
return;
// Second step: find subscript sizes.
SE.findArrayDimensions(Terms, Sizes, ElementSize);
findArrayDimensions(Terms, Sizes, ElementSize);
if (Sizes.empty())
return;
// Third step: compute the access functions for each subscript.
computeAccessFunctions(SE, Subscripts, Sizes);
computeAccessFunctions(Expr, Subscripts, Sizes);
if (Subscripts.empty())
return;
DEBUG({
dbgs() << "succeeded to delinearize " << *this << "\n";
dbgs() << "succeeded to delinearize " << *Expr << "\n";
dbgs() << "ArrayDecl[UnknownSize]";
for (const SCEV *S : Sizes)
dbgs() << "[" << *S << "]";