blob: 4654b98a8c195f1cfa462b11a6c4b48c9ab1fbf4 [file] [log] [blame]
Tobias Grosser120db6b2011-11-07 12:58:54 +00001
2#include "polly/Support/SCEVValidator.h"
3
Tobias Grossereeb776a2012-09-08 14:00:37 +00004#define DEBUG_TYPE "polly-scev-validator"
5#include "llvm/Support/Debug.h"
Tobias Grosser120db6b2011-11-07 12:58:54 +00006#include "llvm/Analysis/ScalarEvolution.h"
7#include "llvm/Analysis/ScalarEvolutionExpressions.h"
8#include "llvm/Analysis/RegionInfo.h"
9
Tobias Grosser60b54f12011-11-08 15:41:28 +000010#include <vector>
11
Tobias Grosser120db6b2011-11-07 12:58:54 +000012using namespace llvm;
13
14namespace SCEVType {
Tobias Grosserb1f07c52011-11-17 12:56:17 +000015 /// @brief The type of a SCEV
16 ///
17 /// To check for the validity of a SCEV we assign to each SCEV a type. The
18 /// possible types are INT, PARAM, IV and INVALID. The order of the types is
19 /// important. The subexpressions of SCEV with a type X can only have a type
20 /// that is smaller or equal than X.
21 enum TYPE {
22 // An integer value.
23 INT,
24
25 // An expression that is constant during the execution of the Scop,
26 // but that may depend on parameters unknown at compile time.
27 PARAM,
28
29 // An expression that may change during the execution of the SCoP.
30 IV,
31
32 // An invalid expression.
33 INVALID
34 };
Tobias Grosser120db6b2011-11-07 12:58:54 +000035}
36
Tobias Grosserb1f07c52011-11-17 12:56:17 +000037/// @brief The result the validator returns for a SCEV expression.
Tobias Grosserfa043f02011-11-17 12:56:19 +000038class ValidatorResult {
Tobias Grosserb1f07c52011-11-17 12:56:17 +000039 /// @brief The type of the expression
Tobias Grosseredb8a282011-11-17 12:56:21 +000040 SCEVType::TYPE Type;
Tobias Grosserb1f07c52011-11-17 12:56:17 +000041
42 /// @brief The set of Parameters in the expression.
Tobias Grosser60b54f12011-11-08 15:41:28 +000043 std::vector<const SCEV*> Parameters;
Tobias Grosser120db6b2011-11-07 12:58:54 +000044
Tobias Grosserfa043f02011-11-17 12:56:19 +000045public:
Tobias Grosserb1f07c52011-11-17 12:56:17 +000046 /// @brief The copy constructor
Tobias Grosseredb8a282011-11-17 12:56:21 +000047 ValidatorResult(const ValidatorResult &Source) {
48 Type = Source.Type;
49 Parameters = Source.Parameters;
Tobias Grosser120db6b2011-11-07 12:58:54 +000050 };
51
Tobias Grosserb1f07c52011-11-17 12:56:17 +000052 /// @brief Construct a result with a certain type and no parameters.
Tobias Grosser371bada2012-03-16 10:16:28 +000053 ValidatorResult(SCEVType::TYPE Type) : Type(Type) {
54 assert(Type != SCEVType::PARAM && "Did you forget to pass the parameter");
55 };
Tobias Grosserb1f07c52011-11-17 12:56:17 +000056
57 /// @brief Construct a result with a certain type and a single parameter.
Tobias Grosseredb8a282011-11-17 12:56:21 +000058 ValidatorResult(SCEVType::TYPE Type, const SCEV *Expr) : Type(Type) {
Tobias Grosser60b54f12011-11-08 15:41:28 +000059 Parameters.push_back(Expr);
60 };
Tobias Grosser120db6b2011-11-07 12:58:54 +000061
Tobias Grossereeb776a2012-09-08 14:00:37 +000062 /// @brief Get the type of the ValidatorResult.
63 SCEVType::TYPE getType() {
64 return Type;
65 }
66
Tobias Grosserb1f07c52011-11-17 12:56:17 +000067 /// @brief Is the analyzed SCEV constant during the execution of the SCoP.
Tobias Grosser120db6b2011-11-07 12:58:54 +000068 bool isConstant() {
Tobias Grosseredb8a282011-11-17 12:56:21 +000069 return Type == SCEVType::INT || Type == SCEVType::PARAM;
Tobias Grosser120db6b2011-11-07 12:58:54 +000070 }
71
Tobias Grosserb1f07c52011-11-17 12:56:17 +000072 /// @brief Is the analyzed SCEV valid.
Tobias Grosser120db6b2011-11-07 12:58:54 +000073 bool isValid() {
Tobias Grosseredb8a282011-11-17 12:56:21 +000074 return Type != SCEVType::INVALID;
Tobias Grosser120db6b2011-11-07 12:58:54 +000075 }
76
Tobias Grosseredb8a282011-11-17 12:56:21 +000077 /// @brief Is the analyzed SCEV of Type IV.
Tobias Grosser120db6b2011-11-07 12:58:54 +000078 bool isIV() {
Tobias Grosseredb8a282011-11-17 12:56:21 +000079 return Type == SCEVType::IV;
Tobias Grosser120db6b2011-11-07 12:58:54 +000080 }
81
Tobias Grosseredb8a282011-11-17 12:56:21 +000082 /// @brief Is the analyzed SCEV of Type INT.
Tobias Grosser120db6b2011-11-07 12:58:54 +000083 bool isINT() {
Tobias Grosseredb8a282011-11-17 12:56:21 +000084 return Type == SCEVType::INT;
Tobias Grosser120db6b2011-11-07 12:58:54 +000085 }
Tobias Grosser60b54f12011-11-08 15:41:28 +000086
Tobias Grossereeb776a2012-09-08 14:00:37 +000087 /// @brief Is the analyzed SCEV of Type PARAM.
88 bool isPARAM() {
89 return Type == SCEVType::PARAM;
90 }
91
Tobias Grosserfa043f02011-11-17 12:56:19 +000092 /// @brief Get the parameters of this validator result.
93 std::vector<const SCEV*> getParameters() {
94 return Parameters;
95 }
96
Tobias Grosserb1f07c52011-11-17 12:56:17 +000097 /// @brief Add the parameters of Source to this result.
Tobias Grosserfa043f02011-11-17 12:56:19 +000098 void addParamsFrom(class ValidatorResult &Source) {
Tobias Grosserb1f07c52011-11-17 12:56:17 +000099 Parameters.insert(Parameters.end(),
100 Source.Parameters.begin(),
Tobias Grosser60b54f12011-11-08 15:41:28 +0000101 Source.Parameters.end());
102 }
Tobias Grosserfa043f02011-11-17 12:56:19 +0000103
104 /// @brief Merge a result.
105 ///
Tobias Grosseredb8a282011-11-17 12:56:21 +0000106 /// This means to merge the parameters and to set the Type to the most
107 /// specific Type that matches both.
Tobias Grosserfa043f02011-11-17 12:56:19 +0000108 void merge(class ValidatorResult &ToMerge) {
Tobias Grosseredb8a282011-11-17 12:56:21 +0000109 Type = std::max(Type, ToMerge.Type);
Tobias Grosserfa043f02011-11-17 12:56:19 +0000110 addParamsFrom(ToMerge);
111 }
Tobias Grosser540757b2012-03-16 10:12:37 +0000112
113 void print(raw_ostream &OS) {
114 switch (Type) {
115 case SCEVType::INT:
Tobias Grossereeb776a2012-09-08 14:00:37 +0000116 OS << "SCEVType::INT";
Tobias Grosser540757b2012-03-16 10:12:37 +0000117 break;
118 case SCEVType::PARAM:
Tobias Grossereeb776a2012-09-08 14:00:37 +0000119 OS << "SCEVType::PARAM";
Tobias Grosser540757b2012-03-16 10:12:37 +0000120 break;
121 case SCEVType::IV:
Tobias Grossereeb776a2012-09-08 14:00:37 +0000122 OS << "SCEVType::IV";
Tobias Grosser540757b2012-03-16 10:12:37 +0000123 break;
124 case SCEVType::INVALID:
Tobias Grossereeb776a2012-09-08 14:00:37 +0000125 OS << "SCEVType::INVALID";
Tobias Grosser540757b2012-03-16 10:12:37 +0000126 break;
127 }
128 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000129};
130
Tobias Grosser540757b2012-03-16 10:12:37 +0000131raw_ostream &operator<<(raw_ostream &OS, class ValidatorResult &VR) {
132 VR.print(OS);
133 return OS;
134}
135
Tobias Grosser120db6b2011-11-07 12:58:54 +0000136/// Check if a SCEV is valid in a SCoP.
137struct SCEVValidator
Tobias Grosserfa043f02011-11-17 12:56:19 +0000138 : public SCEVVisitor<SCEVValidator, class ValidatorResult> {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000139private:
140 const Region *R;
141 ScalarEvolution &SE;
Tobias Grossere5e171e2011-11-10 12:45:03 +0000142 const Value *BaseAddress;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000143
144public:
145 SCEVValidator(const Region *R, ScalarEvolution &SE,
Tobias Grossere5e171e2011-11-10 12:45:03 +0000146 const Value *BaseAddress) : R(R), SE(SE),
Tobias Grosser120db6b2011-11-07 12:58:54 +0000147 BaseAddress(BaseAddress) {};
148
Tobias Grosserfa043f02011-11-17 12:56:19 +0000149 class ValidatorResult visitConstant(const SCEVConstant *Constant) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000150 return ValidatorResult(SCEVType::INT);
151 }
152
Tobias Grosserfa043f02011-11-17 12:56:19 +0000153 class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000154 ValidatorResult Op = visit(Expr->getOperand());
155
Tobias Grossereeb776a2012-09-08 14:00:37 +0000156 switch (Op.getType()) {
157 case SCEVType::INT:
158 case SCEVType::PARAM:
159 // We currently do not represent a truncate expression as an affine
160 // expression. If it is constant during Scop execution, we treat it as a
161 // parameter.
162 return ValidatorResult(SCEVType::PARAM, Expr);
163 case SCEVType::IV:
164 DEBUG(dbgs() << "INVALID: Truncation of SCEVType::IV expression");
165 return ValidatorResult(SCEVType::INVALID);
166 case SCEVType::INVALID:
167 return Op;
168 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000169
Tobias Grossereeb776a2012-09-08 14:00:37 +0000170 llvm_unreachable("Unknown SCEVType");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000171 }
172
Tobias Grosserfa043f02011-11-17 12:56:19 +0000173 class ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000174 ValidatorResult Op = visit(Expr->getOperand());
175
Tobias Grossereeb776a2012-09-08 14:00:37 +0000176 switch (Op.getType()) {
177 case SCEVType::INT:
178 case SCEVType::PARAM:
179 // We currently do not represent a truncate expression as an affine
180 // expression. If it is constant during Scop execution, we treat it as a
181 // parameter.
182 return ValidatorResult(SCEVType::PARAM, Expr);
183 case SCEVType::IV:
184 DEBUG(dbgs() << "INVALID: ZeroExtend of SCEVType::IV expression");
185 return ValidatorResult(SCEVType::INVALID);
186 case SCEVType::INVALID:
187 return Op;
188 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000189
Tobias Grossereeb776a2012-09-08 14:00:37 +0000190 llvm_unreachable("Unknown SCEVType");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000191 }
192
Tobias Grosserfa043f02011-11-17 12:56:19 +0000193 class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000194 // We currently allow only signed SCEV expressions. In the case of a
195 // signed value, a sign extend is a noop.
196 //
197 // TODO: Reconsider this when we add support for unsigned values.
198 return visit(Expr->getOperand());
199 }
200
Tobias Grosserfa043f02011-11-17 12:56:19 +0000201 class ValidatorResult visitAddExpr(const SCEVAddExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000202 ValidatorResult Return(SCEVType::INT);
203
204 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
205 ValidatorResult Op = visit(Expr->getOperand(i));
Tobias Grosserfa043f02011-11-17 12:56:19 +0000206 Return.merge(Op);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000207
208 // Early exit.
209 if (!Return.isValid())
210 break;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000211 }
212
213 // TODO: Check for NSW and NUW.
214 return Return;
215 }
216
Tobias Grosserfa043f02011-11-17 12:56:19 +0000217 class ValidatorResult visitMulExpr(const SCEVMulExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000218 ValidatorResult Return(SCEVType::INT);
219
220 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
221 ValidatorResult Op = visit(Expr->getOperand(i));
222
Tobias Grosserfa043f02011-11-17 12:56:19 +0000223 if (Op.isINT())
Tobias Grosser120db6b2011-11-07 12:58:54 +0000224 continue;
225
Tobias Grossereeb776a2012-09-08 14:00:37 +0000226 if ((Op.isIV() || Op.isPARAM()) && !Return.isINT() ) {
227 DEBUG(dbgs() << "INVALID: More than one non-int operand in MulExpr\n"
228 << "\tExpr: " << *Expr << "\n"
229 << "\tPrevious expression type: " << Return << "\n"
230 << "\tNext operand (" << Op << "): "
231 << *Expr->getOperand(i) << "\n");
232
Tobias Grosser120db6b2011-11-07 12:58:54 +0000233 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000234 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000235
Tobias Grosserfa043f02011-11-17 12:56:19 +0000236 Return.merge(Op);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000237 }
238
239 // TODO: Check for NSW and NUW.
240 return Return;
241 }
242
Tobias Grosserfa043f02011-11-17 12:56:19 +0000243 class ValidatorResult visitUDivExpr(const SCEVUDivExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000244 ValidatorResult LHS = visit(Expr->getLHS());
245 ValidatorResult RHS = visit(Expr->getRHS());
246
Tobias Grosserf9fbbdf2012-04-09 19:46:05 +0000247 // We currently do not represent an unsigned division as an affine
Tobias Grosser120db6b2011-11-07 12:58:54 +0000248 // expression. If the division is constant during Scop execution we treat it
249 // as a parameter, otherwise we bail out.
250 if (LHS.isConstant() && RHS.isConstant())
Tobias Grosser60b54f12011-11-08 15:41:28 +0000251 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000252
Tobias Grossereeb776a2012-09-08 14:00:37 +0000253 DEBUG(dbgs() << "INVALID: unsigned division of non-constant expressions");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000254 return ValidatorResult(SCEVType::INVALID);
255 }
256
Tobias Grosserfa043f02011-11-17 12:56:19 +0000257 class ValidatorResult visitAddRecExpr(const SCEVAddRecExpr *Expr) {
Tobias Grossereeb776a2012-09-08 14:00:37 +0000258 if (!Expr->isAffine()) {
259 DEBUG(dbgs() << "INVALID: AddRec is not affine");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000260 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000261 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000262
263 ValidatorResult Start = visit(Expr->getStart());
264 ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE));
265
Tobias Grossereeb776a2012-09-08 14:00:37 +0000266 if (!Start.isValid())
267 return Start;
268
269 if (!Recurrence.isValid())
270 return Recurrence;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000271
Tobias Grosserbcc0a0d2011-11-17 12:56:14 +0000272 if (R->contains(Expr->getLoop())) {
273 if (Recurrence.isINT()) {
274 ValidatorResult Result(SCEVType::IV);
275 Result.addParamsFrom(Start);
276 return Result;
277 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000278
Tobias Grossereeb776a2012-09-08 14:00:37 +0000279 DEBUG(dbgs() << "INVALID: AddRec within scop has non-int"
280 "recurrence part");
Tobias Grosserbcc0a0d2011-11-17 12:56:14 +0000281 return ValidatorResult(SCEVType::INVALID);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000282 }
283
Tobias Grossereeb776a2012-09-08 14:00:37 +0000284 assert (Start.isConstant() && Recurrence.isConstant()
285 && "Expected 'Start' and 'Recurrence' to be constant");
286 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000287 }
288
Tobias Grosserfa043f02011-11-17 12:56:19 +0000289 class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) {
Tobias Grosser371bada2012-03-16 10:16:28 +0000290 ValidatorResult Return(SCEVType::INT, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000291
292 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
293 ValidatorResult Op = visit(Expr->getOperand(i));
294
295 if (!Op.isValid())
Tobias Grossereeb776a2012-09-08 14:00:37 +0000296 return Op;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000297
Tobias Grosserfa043f02011-11-17 12:56:19 +0000298 Return.merge(Op);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000299 }
300
301 return Return;
302 }
303
Tobias Grosserfa043f02011-11-17 12:56:19 +0000304 class ValidatorResult visitUMaxExpr(const SCEVUMaxExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000305 // We do not support unsigned operations. If 'Expr' is constant during Scop
306 // execution we treat this as a parameter, otherwise we bail out.
307 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
308 ValidatorResult Op = visit(Expr->getOperand(i));
309
Tobias Grossereeb776a2012-09-08 14:00:37 +0000310 if (!Op.isConstant()) {
311 DEBUG(dbgs() << "INVALID: UMaxExpr has a non-constant operand");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000312 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000313 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000314 }
315
Tobias Grosser371bada2012-03-16 10:16:28 +0000316 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000317 }
318
Tobias Grosser7ffe4e82011-11-17 12:56:10 +0000319 ValidatorResult visitUnknown(const SCEVUnknown *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000320 Value *V = Expr->getValue();
321
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000322 // We currently only support integer types. It may be useful to support
323 // pointer types, e.g. to support code like:
324 //
325 // if (A)
326 // A[i] = 1;
327 //
328 // See test/CodeGen/20120316-InvalidCast.ll
Tobias Grossereeb776a2012-09-08 14:00:37 +0000329 if (!Expr->getType()->isIntegerTy()) {
330 DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer type");
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000331 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000332 }
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000333
Tobias Grossereeb776a2012-09-08 14:00:37 +0000334 if (isa<UndefValue>(V)) {
335 DEBUG(dbgs() << "INVALID: UnknownExpr references an undef value");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000336 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000337 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000338
Tobias Grosser120db6b2011-11-07 12:58:54 +0000339 if (Instruction *I = dyn_cast<Instruction>(Expr->getValue()))
Tobias Grossereeb776a2012-09-08 14:00:37 +0000340 if (R->contains(I)) {
341 DEBUG(dbgs() << "INVALID: UnknownExpr references an instruction "
342 "within the region\n");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000343 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000344 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000345
Tobias Grossereeb776a2012-09-08 14:00:37 +0000346 if (BaseAddress == V) {
347 DEBUG(dbgs() << "INVALID: UnknownExpr references BaseAddress\n");
Tobias Grossere5e171e2011-11-10 12:45:03 +0000348 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000349 }
Tobias Grossere5e171e2011-11-10 12:45:03 +0000350
351 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000352 }
353};
354
355namespace polly {
356 bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
Tobias Grossere5e171e2011-11-10 12:45:03 +0000357 const Value *BaseAddress) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000358 if (isa<SCEVCouldNotCompute>(Expr))
359 return false;
360
Tobias Grosser120db6b2011-11-07 12:58:54 +0000361 SCEVValidator Validator(R, SE, BaseAddress);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000362 DEBUG(
363 dbgs() << "\n";
364 dbgs() << "Expr: " << *Expr << "\n";
365 dbgs() << "Region: " << R->getNameStr() << "\n";
366 dbgs() << " -> ");
367
Tobias Grosser120db6b2011-11-07 12:58:54 +0000368 ValidatorResult Result = Validator.visit(Expr);
369
Tobias Grossereeb776a2012-09-08 14:00:37 +0000370 DEBUG(
371 if (Result.isValid())
372 dbgs() << "VALID\n";
373 dbgs() << "\n";
374 );
375
Tobias Grosser120db6b2011-11-07 12:58:54 +0000376 return Result.isValid();
377 }
Tobias Grosser60b54f12011-11-08 15:41:28 +0000378
379 std::vector<const SCEV*> getParamsInAffineExpr(const Region *R,
380 const SCEV *Expr,
381 ScalarEvolution &SE,
Tobias Grossere5e171e2011-11-10 12:45:03 +0000382 const Value *BaseAddress) {
Tobias Grosser60b54f12011-11-08 15:41:28 +0000383 if (isa<SCEVCouldNotCompute>(Expr))
384 return std::vector<const SCEV*>();
385
Tobias Grosser60b54f12011-11-08 15:41:28 +0000386 SCEVValidator Validator(R, SE, BaseAddress);
387 ValidatorResult Result = Validator.visit(Expr);
388
Tobias Grosserfa043f02011-11-17 12:56:19 +0000389 return Result.getParameters();
Tobias Grosser60b54f12011-11-08 15:41:28 +0000390 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000391}
392
393