Detect Parameters directly on the SCEV.
Instead of using TempScop to find parameters, we detect them directly
on the SCEV. This allows us to remove the TempScop parameter detection
in a subsequent commit.
This fixes a bug reported by Marcello Maggioni <hayarms@gmail.com>
llvm-svn: 144087
diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp
index 52de6bc..fe70510 100644
--- a/polly/lib/Support/SCEVValidator.cpp
+++ b/polly/lib/Support/SCEVValidator.cpp
@@ -5,6 +5,8 @@
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/RegionInfo.h"
+#include <vector>
+
using namespace llvm;
namespace SCEVType {
@@ -13,14 +15,19 @@
struct ValidatorResult {
SCEVType::TYPE type;
+ std::vector<const SCEV*> Parameters;
ValidatorResult() : type(SCEVType::INVALID) {};
ValidatorResult(const ValidatorResult &vres) {
type = vres.type;
+ Parameters = vres.Parameters;
};
ValidatorResult(SCEVType::TYPE type) : type(type) {};
+ ValidatorResult(SCEVType::TYPE type, const SCEV* Expr) : type(type) {
+ Parameters.push_back(Expr);
+ };
bool isConstant() {
return type == SCEVType::INT || type == SCEVType::PARAM;
@@ -37,6 +44,11 @@
bool isINT() {
return type == SCEVType::INT;
}
+
+ void addParamsFrom(struct ValidatorResult &Source) {
+ Parameters.insert(Parameters.end(), Source.Parameters.begin(),
+ Source.Parameters.end());
+ }
};
/// Check if a SCEV is valid in a SCoP.
@@ -63,7 +75,7 @@
// expression. If it is constant during Scop execution, we treat it as a
// parameter, otherwise we bail out.
if (Op.isConstant())
- return ValidatorResult(SCEVType::PARAM);
+ return ValidatorResult(SCEVType::PARAM, Expr);
return ValidatorResult (SCEVType::INVALID);
}
@@ -75,7 +87,7 @@
// expression. If it is constant during Scop execution, we treat it as a
// parameter, otherwise we bail out.
if (Op.isConstant())
- return ValidatorResult (SCEVType::PARAM);
+ return ValidatorResult (SCEVType::PARAM, Expr);
return ValidatorResult(SCEVType::INVALID);
}
@@ -98,6 +110,7 @@
return ValidatorResult(SCEVType::INVALID);
Return.type = std::max(Return.type, Op.type);
+ Return.addParamsFrom(Op);
}
// TODO: Check for NSW and NUW.
@@ -117,6 +130,7 @@
return ValidatorResult(SCEVType::INVALID);
Return.type = Op.type;
+ Return.addParamsFrom(Op);
}
// TODO: Check for NSW and NUW.
@@ -131,7 +145,7 @@
// expression. If the division is constant during Scop execution we treat it
// as a parameter, otherwise we bail out.
if (LHS.isConstant() && RHS.isConstant())
- return ValidatorResult(SCEVType::PARAM);
+ return ValidatorResult(SCEVType::PARAM, Expr);
return ValidatorResult(SCEVType::INVALID);
}
@@ -151,13 +165,15 @@
if (Start.isIV())
return ValidatorResult(SCEVType::INVALID);
else
- return ValidatorResult(SCEVType::PARAM);
+ return ValidatorResult(SCEVType::PARAM, Expr);
}
if (!Recurrence.isINT())
return ValidatorResult(SCEVType::INVALID);
- return ValidatorResult(SCEVType::IV);
+ ValidatorResult Result(SCEVType::IV);
+ Result.addParamsFrom(Start);
+ return Result;
}
struct ValidatorResult visitSMaxExpr(const SCEVSMaxExpr* Expr) {
@@ -170,12 +186,15 @@
return ValidatorResult(SCEVType::INVALID);
Return.type = std::max(Return.type, Op.type);
+ Return.addParamsFrom(Op);
}
return Return;
}
struct ValidatorResult visitUMaxExpr(const SCEVUMaxExpr* Expr) {
+ ValidatorResult Return(SCEVType::PARAM);
+
// We do not support unsigned operations. If 'Expr' is constant during Scop
// execution we treat this as a parameter, otherwise we bail out.
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
@@ -183,9 +202,11 @@
if (!Op.isConstant())
return ValidatorResult(SCEVType::INVALID);
+
+ Return.addParamsFrom(Op);
}
- return ValidatorResult(SCEVType::PARAM);
+ return Return;
}
ValidatorResult visitUnknown(const SCEVUnknown* Expr) {
@@ -208,7 +229,7 @@
if (BaseAddress)
return ValidatorResult(SCEVType::PARAM);
else
- return ValidatorResult(SCEVType::PARAM);
+ return ValidatorResult(SCEVType::PARAM, Expr);
}
};
@@ -226,6 +247,22 @@
return Result.isValid();
}
+
+ std::vector<const SCEV*> getParamsInAffineExpr(const Region *R,
+ const SCEV *Expr,
+ ScalarEvolution &SE,
+ Value **BaseAddress) {
+ if (isa<SCEVCouldNotCompute>(Expr))
+ return std::vector<const SCEV*>();
+
+ if (BaseAddress)
+ *BaseAddress = NULL;
+
+ SCEVValidator Validator(R, SE, BaseAddress);
+ ValidatorResult Result = Validator.visit(Expr);
+
+ return Result.Parameters;
+ }
}