blob: b06e8beb7f93c6c7ffb9ee2d87c64c74381711e7 [file] [log] [blame]
Tobias Grosser120db6b2011-11-07 12:58:54 +00001
2#include "polly/Support/SCEVValidator.h"
Sebastian Pop97cb8132013-03-18 20:21:13 +00003#include "polly/ScopInfo.h"
Tobias Grosserba0d0922015-05-09 09:13:42 +00004#include "llvm/Analysis/RegionInfo.h"
Tobias Grosser120db6b2011-11-07 12:58:54 +00005#include "llvm/Analysis/ScalarEvolution.h"
6#include "llvm/Analysis/ScalarEvolutionExpressions.h"
Chandler Carruth95fef942014-04-22 03:30:19 +00007#include "llvm/Support/Debug.h"
Tobias Grosser60b54f12011-11-08 15:41:28 +00008#include <vector>
9
Tobias Grosser120db6b2011-11-07 12:58:54 +000010using namespace llvm;
11
Chandler Carruth95fef942014-04-22 03:30:19 +000012#define DEBUG_TYPE "polly-scev-validator"
13
Tobias Grosser120db6b2011-11-07 12:58:54 +000014namespace SCEVType {
Tobias Grosserde49b8f2013-02-22 08:21:52 +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.
21enum TYPE {
22 // An integer value.
23 INT,
Tobias Grosserb1f07c52011-11-17 12:56:17 +000024
Tobias Grosserde49b8f2013-02-22 08:21:52 +000025 // An expression that is constant during the execution of the Scop,
26 // but that may depend on parameters unknown at compile time.
27 PARAM,
Tobias Grosserb1f07c52011-11-17 12:56:17 +000028
Tobias Grosserde49b8f2013-02-22 08:21:52 +000029 // An expression that may change during the execution of the SCoP.
30 IV,
Tobias Grosserb1f07c52011-11-17 12:56:17 +000031
Tobias Grosserde49b8f2013-02-22 08:21:52 +000032 // 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 Grosserde49b8f2013-02-22 08:21:52 +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 Grosserde49b8f2013-02-22 08:21:52 +000050 }
Tobias Grosser120db6b2011-11-07 12:58:54 +000051
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");
Tobias Grosserde49b8f2013-02-22 08:21:52 +000055 }
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);
Tobias Grosserde49b8f2013-02-22 08:21:52 +000060 }
Tobias Grosser120db6b2011-11-07 12:58:54 +000061
Tobias Grossereeb776a2012-09-08 14:00:37 +000062 /// @brief Get the type of the ValidatorResult.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000063 SCEVType::TYPE getType() { return Type; }
Tobias Grossereeb776a2012-09-08 14:00:37 +000064
Tobias Grosserb1f07c52011-11-17 12:56:17 +000065 /// @brief Is the analyzed SCEV constant during the execution of the SCoP.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000066 bool isConstant() { return Type == SCEVType::INT || Type == SCEVType::PARAM; }
Tobias Grosser120db6b2011-11-07 12:58:54 +000067
Tobias Grosserb1f07c52011-11-17 12:56:17 +000068 /// @brief Is the analyzed SCEV valid.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000069 bool isValid() { return Type != SCEVType::INVALID; }
Tobias Grosser120db6b2011-11-07 12:58:54 +000070
Tobias Grosseredb8a282011-11-17 12:56:21 +000071 /// @brief Is the analyzed SCEV of Type IV.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000072 bool isIV() { return Type == SCEVType::IV; }
Tobias Grosser120db6b2011-11-07 12:58:54 +000073
Tobias Grosseredb8a282011-11-17 12:56:21 +000074 /// @brief Is the analyzed SCEV of Type INT.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000075 bool isINT() { return Type == SCEVType::INT; }
Tobias Grosser60b54f12011-11-08 15:41:28 +000076
Tobias Grossereeb776a2012-09-08 14:00:37 +000077 /// @brief Is the analyzed SCEV of Type PARAM.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000078 bool isPARAM() { return Type == SCEVType::PARAM; }
Tobias Grossereeb776a2012-09-08 14:00:37 +000079
Tobias Grosserfa043f02011-11-17 12:56:19 +000080 /// @brief Get the parameters of this validator result.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000081 std::vector<const SCEV *> getParameters() { return Parameters; }
Tobias Grosserfa043f02011-11-17 12:56:19 +000082
Tobias Grosserb1f07c52011-11-17 12:56:17 +000083 /// @brief Add the parameters of Source to this result.
Johannes Doerfertecc33a12015-02-26 19:33:42 +000084 void addParamsFrom(const ValidatorResult &Source) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +000085 Parameters.insert(Parameters.end(), Source.Parameters.begin(),
Tobias Grosser60b54f12011-11-08 15:41:28 +000086 Source.Parameters.end());
87 }
Tobias Grosserfa043f02011-11-17 12:56:19 +000088
89 /// @brief Merge a result.
90 ///
Tobias Grosseredb8a282011-11-17 12:56:21 +000091 /// This means to merge the parameters and to set the Type to the most
92 /// specific Type that matches both.
Johannes Doerfertecc33a12015-02-26 19:33:42 +000093 void merge(const ValidatorResult &ToMerge) {
Tobias Grosseredb8a282011-11-17 12:56:21 +000094 Type = std::max(Type, ToMerge.Type);
Tobias Grosserfa043f02011-11-17 12:56:19 +000095 addParamsFrom(ToMerge);
96 }
Tobias Grosser540757b2012-03-16 10:12:37 +000097
98 void print(raw_ostream &OS) {
99 switch (Type) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000100 case SCEVType::INT:
101 OS << "SCEVType::INT";
Tobias Grosser540757b2012-03-16 10:12:37 +0000102 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000103 case SCEVType::PARAM:
104 OS << "SCEVType::PARAM";
Tobias Grosser540757b2012-03-16 10:12:37 +0000105 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000106 case SCEVType::IV:
107 OS << "SCEVType::IV";
Tobias Grosser540757b2012-03-16 10:12:37 +0000108 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000109 case SCEVType::INVALID:
110 OS << "SCEVType::INVALID";
Tobias Grosser540757b2012-03-16 10:12:37 +0000111 break;
112 }
113 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000114};
115
Tobias Grosser540757b2012-03-16 10:12:37 +0000116raw_ostream &operator<<(raw_ostream &OS, class ValidatorResult &VR) {
117 VR.print(OS);
118 return OS;
119}
120
Tobias Grosser120db6b2011-11-07 12:58:54 +0000121/// Check if a SCEV is valid in a SCoP.
Tobias Grosser58032cb2013-06-23 01:29:29 +0000122struct SCEVValidator
123 : public SCEVVisitor<SCEVValidator, class ValidatorResult> {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000124private:
125 const Region *R;
126 ScalarEvolution &SE;
Tobias Grossere5e171e2011-11-10 12:45:03 +0000127 const Value *BaseAddress;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000128
129public:
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000130 SCEVValidator(const Region *R, ScalarEvolution &SE, const Value *BaseAddress)
131 : R(R), SE(SE), BaseAddress(BaseAddress) {}
Tobias Grosser120db6b2011-11-07 12:58:54 +0000132
Tobias Grosserfa043f02011-11-17 12:56:19 +0000133 class ValidatorResult visitConstant(const SCEVConstant *Constant) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000134 return ValidatorResult(SCEVType::INT);
135 }
136
Tobias Grosserfa043f02011-11-17 12:56:19 +0000137 class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000138 ValidatorResult Op = visit(Expr->getOperand());
139
Tobias Grossereeb776a2012-09-08 14:00:37 +0000140 switch (Op.getType()) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000141 case SCEVType::INT:
142 case SCEVType::PARAM:
143 // We currently do not represent a truncate expression as an affine
144 // expression. If it is constant during Scop execution, we treat it as a
145 // parameter.
146 return ValidatorResult(SCEVType::PARAM, Expr);
147 case SCEVType::IV:
148 DEBUG(dbgs() << "INVALID: Truncation of SCEVType::IV expression");
149 return ValidatorResult(SCEVType::INVALID);
150 case SCEVType::INVALID:
151 return Op;
Tobias Grossereeb776a2012-09-08 14:00:37 +0000152 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000153
Tobias Grossereeb776a2012-09-08 14:00:37 +0000154 llvm_unreachable("Unknown SCEVType");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000155 }
156
Tobias Grosserfa043f02011-11-17 12:56:19 +0000157 class ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
Tobias Grosserf4daf342014-08-16 09:08:55 +0000158 ValidatorResult Op = visit(Expr->getOperand());
Tobias Grosser120db6b2011-11-07 12:58:54 +0000159
Tobias Grossereeb776a2012-09-08 14:00:37 +0000160 switch (Op.getType()) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000161 case SCEVType::INT:
162 case SCEVType::PARAM:
163 // We currently do not represent a truncate expression as an affine
164 // expression. If it is constant during Scop execution, we treat it as a
165 // parameter.
166 return ValidatorResult(SCEVType::PARAM, Expr);
167 case SCEVType::IV:
168 DEBUG(dbgs() << "INVALID: ZeroExtend of SCEVType::IV expression");
169 return ValidatorResult(SCEVType::INVALID);
170 case SCEVType::INVALID:
171 return Op;
Tobias Grossereeb776a2012-09-08 14:00:37 +0000172 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000173
Tobias Grossereeb776a2012-09-08 14:00:37 +0000174 llvm_unreachable("Unknown SCEVType");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000175 }
176
Tobias Grosserfa043f02011-11-17 12:56:19 +0000177 class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000178 // We currently allow only signed SCEV expressions. In the case of a
179 // signed value, a sign extend is a noop.
180 //
181 // TODO: Reconsider this when we add support for unsigned values.
182 return visit(Expr->getOperand());
183 }
184
Tobias Grosserfa043f02011-11-17 12:56:19 +0000185 class ValidatorResult visitAddExpr(const SCEVAddExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000186 ValidatorResult Return(SCEVType::INT);
187
188 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
189 ValidatorResult Op = visit(Expr->getOperand(i));
Tobias Grosserfa043f02011-11-17 12:56:19 +0000190 Return.merge(Op);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000191
192 // Early exit.
193 if (!Return.isValid())
194 break;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000195 }
196
197 // TODO: Check for NSW and NUW.
198 return Return;
199 }
200
Tobias Grosserfa043f02011-11-17 12:56:19 +0000201 class ValidatorResult visitMulExpr(const SCEVMulExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000202 ValidatorResult Return(SCEVType::INT);
203
Tobias Grosser3ed26002013-04-14 13:15:59 +0000204 bool HasMultipleParams = false;
205
Tobias Grosser120db6b2011-11-07 12:58:54 +0000206 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
207 ValidatorResult Op = visit(Expr->getOperand(i));
208
Tobias Grosserfa043f02011-11-17 12:56:19 +0000209 if (Op.isINT())
Tobias Grosser120db6b2011-11-07 12:58:54 +0000210 continue;
211
Tobias Grosserecb50922013-04-10 07:42:28 +0000212 if (Op.isPARAM() && Return.isPARAM()) {
Tobias Grossere602a072013-05-07 07:30:56 +0000213 HasMultipleParams = true;
Tobias Grosserecb50922013-04-10 07:42:28 +0000214 continue;
215 }
216
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000217 if ((Op.isIV() || Op.isPARAM()) && !Return.isINT()) {
Tobias Grossereeb776a2012-09-08 14:00:37 +0000218 DEBUG(dbgs() << "INVALID: More than one non-int operand in MulExpr\n"
219 << "\tExpr: " << *Expr << "\n"
220 << "\tPrevious expression type: " << Return << "\n"
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000221 << "\tNext operand (" << Op
222 << "): " << *Expr->getOperand(i) << "\n");
Tobias Grossereeb776a2012-09-08 14:00:37 +0000223
Tobias Grosser120db6b2011-11-07 12:58:54 +0000224 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000225 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000226
Tobias Grosserfa043f02011-11-17 12:56:19 +0000227 Return.merge(Op);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000228 }
229
Tobias Grosser2a586c32015-04-05 14:57:50 +0000230 if (HasMultipleParams && Return.isValid())
Tobias Grosser3ed26002013-04-14 13:15:59 +0000231 return ValidatorResult(SCEVType::PARAM, Expr);
232
Tobias Grosser120db6b2011-11-07 12:58:54 +0000233 // TODO: Check for NSW and NUW.
234 return Return;
235 }
236
Tobias Grosserfa043f02011-11-17 12:56:19 +0000237 class ValidatorResult visitUDivExpr(const SCEVUDivExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000238 ValidatorResult LHS = visit(Expr->getLHS());
239 ValidatorResult RHS = visit(Expr->getRHS());
240
Tobias Grosserf9fbbdf2012-04-09 19:46:05 +0000241 // We currently do not represent an unsigned division as an affine
Tobias Grosser120db6b2011-11-07 12:58:54 +0000242 // expression. If the division is constant during Scop execution we treat it
243 // as a parameter, otherwise we bail out.
244 if (LHS.isConstant() && RHS.isConstant())
Tobias Grosser60b54f12011-11-08 15:41:28 +0000245 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000246
Tobias Grossereeb776a2012-09-08 14:00:37 +0000247 DEBUG(dbgs() << "INVALID: unsigned division of non-constant expressions");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000248 return ValidatorResult(SCEVType::INVALID);
249 }
250
Tobias Grosserfa043f02011-11-17 12:56:19 +0000251 class ValidatorResult visitAddRecExpr(const SCEVAddRecExpr *Expr) {
Tobias Grossereeb776a2012-09-08 14:00:37 +0000252 if (!Expr->isAffine()) {
253 DEBUG(dbgs() << "INVALID: AddRec is not affine");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000254 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000255 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000256
257 ValidatorResult Start = visit(Expr->getStart());
258 ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE));
259
Tobias Grossereeb776a2012-09-08 14:00:37 +0000260 if (!Start.isValid())
261 return Start;
262
263 if (!Recurrence.isValid())
264 return Recurrence;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000265
Tobias Grosserbcc0a0d2011-11-17 12:56:14 +0000266 if (R->contains(Expr->getLoop())) {
267 if (Recurrence.isINT()) {
268 ValidatorResult Result(SCEVType::IV);
269 Result.addParamsFrom(Start);
270 return Result;
271 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000272
Tobias Grossereeb776a2012-09-08 14:00:37 +0000273 DEBUG(dbgs() << "INVALID: AddRec within scop has non-int"
274 "recurrence part");
Tobias Grosserbcc0a0d2011-11-17 12:56:14 +0000275 return ValidatorResult(SCEVType::INVALID);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000276 }
277
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000278 assert(Start.isConstant() && Recurrence.isConstant() &&
279 "Expected 'Start' and 'Recurrence' to be constant");
Tobias Grossere42ddb92013-08-05 15:14:15 +0000280
281 // Directly generate ValidatorResult for Expr if 'start' is zero.
282 if (Expr->getStart()->isZero())
283 return ValidatorResult(SCEVType::PARAM, Expr);
284
285 // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
286 // if 'start' is not zero.
287 const SCEV *ZeroStartExpr = SE.getAddRecExpr(
288 SE.getConstant(Expr->getStart()->getType(), 0),
Johannes Doerfertd5d8f672015-04-26 19:55:21 +0000289 Expr->getStepRecurrence(SE), Expr->getLoop(), Expr->getNoWrapFlags());
Tobias Grossere42ddb92013-08-05 15:14:15 +0000290
291 ValidatorResult ZeroStartResult =
292 ValidatorResult(SCEVType::PARAM, ZeroStartExpr);
293 ZeroStartResult.addParamsFrom(Start);
294
295 return ZeroStartResult;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000296 }
297
Tobias Grosserfa043f02011-11-17 12:56:19 +0000298 class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) {
Tobias Grosser7b6f9ba2013-12-09 21:51:46 +0000299 ValidatorResult Return(SCEVType::INT);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000300
301 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
302 ValidatorResult Op = visit(Expr->getOperand(i));
303
304 if (!Op.isValid())
Tobias Grossereeb776a2012-09-08 14:00:37 +0000305 return Op;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000306
Tobias Grosserfa043f02011-11-17 12:56:19 +0000307 Return.merge(Op);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000308 }
309
310 return Return;
311 }
312
Tobias Grosserfa043f02011-11-17 12:56:19 +0000313 class ValidatorResult visitUMaxExpr(const SCEVUMaxExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000314 // We do not support unsigned operations. If 'Expr' is constant during Scop
315 // execution we treat this as a parameter, otherwise we bail out.
316 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
317 ValidatorResult Op = visit(Expr->getOperand(i));
318
Tobias Grossereeb776a2012-09-08 14:00:37 +0000319 if (!Op.isConstant()) {
320 DEBUG(dbgs() << "INVALID: UMaxExpr has a non-constant operand");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000321 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000322 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000323 }
324
Tobias Grosser371bada2012-03-16 10:16:28 +0000325 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000326 }
327
Johannes Doerfertb9d18882015-02-11 14:54:50 +0000328 ValidatorResult visitGenericInst(Instruction *I, const SCEV *S) {
329 if (R->contains(I)) {
330 DEBUG(dbgs() << "INVALID: UnknownExpr references an instruction "
331 "within the region\n");
332 return ValidatorResult(SCEVType::INVALID);
333 }
334
335 return ValidatorResult(SCEVType::PARAM, S);
336 }
337
338 ValidatorResult visitSDivInstruction(Instruction *SDiv, const SCEV *S) {
339 assert(SDiv->getOpcode() == Instruction::SDiv &&
340 "Assumed SDiv instruction!");
341
342 auto *Divisor = SDiv->getOperand(1);
343 auto *CI = dyn_cast<ConstantInt>(Divisor);
344 if (!CI)
345 return visitGenericInst(SDiv, S);
346
347 auto *Dividend = SDiv->getOperand(0);
348 auto *DividendSCEV = SE.getSCEV(Dividend);
349 return visit(DividendSCEV);
350 }
351
Tobias Grosser7ffe4e82011-11-17 12:56:10 +0000352 ValidatorResult visitUnknown(const SCEVUnknown *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000353 Value *V = Expr->getValue();
354
Tobias Grosser55bc4c02015-01-08 19:26:53 +0000355 if (!(Expr->getType()->isIntegerTy() || Expr->getType()->isPointerTy())) {
356 DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer or pointer type");
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000357 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000358 }
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000359
Tobias Grossereeb776a2012-09-08 14:00:37 +0000360 if (isa<UndefValue>(V)) {
361 DEBUG(dbgs() << "INVALID: UnknownExpr references an undef value");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000362 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000363 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000364
Tobias Grossereeb776a2012-09-08 14:00:37 +0000365 if (BaseAddress == V) {
366 DEBUG(dbgs() << "INVALID: UnknownExpr references BaseAddress\n");
Tobias Grossere5e171e2011-11-10 12:45:03 +0000367 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000368 }
Tobias Grossere5e171e2011-11-10 12:45:03 +0000369
Johannes Doerfertb9d18882015-02-11 14:54:50 +0000370 if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) {
371 switch (I->getOpcode()) {
372 case Instruction::SDiv:
373 return visitSDivInstruction(I, Expr);
374 default:
375 return visitGenericInst(I, Expr);
376 }
377 }
378
Tobias Grossere5e171e2011-11-10 12:45:03 +0000379 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000380 }
381};
382
Sebastian Pop97cb8132013-03-18 20:21:13 +0000383/// @brief Check whether a SCEV refers to an SSA name defined inside a region.
384///
Tobias Grosser58032cb2013-06-23 01:29:29 +0000385struct SCEVInRegionDependences
386 : public SCEVVisitor<SCEVInRegionDependences, bool> {
Sebastian Pop97cb8132013-03-18 20:21:13 +0000387public:
Sebastian Pop97cb8132013-03-18 20:21:13 +0000388 /// Returns true when the SCEV has SSA names defined in region R.
389 static bool hasDependences(const SCEV *S, const Region *R) {
390 SCEVInRegionDependences Ignore(R);
391 return Ignore.visit(S);
392 }
393
394 SCEVInRegionDependences(const Region *R) : R(R) {}
395
396 bool visit(const SCEV *Expr) {
397 return SCEVVisitor<SCEVInRegionDependences, bool>::visit(Expr);
398 }
399
400 bool visitConstant(const SCEVConstant *Constant) { return false; }
401
402 bool visitTruncateExpr(const SCEVTruncateExpr *Expr) {
403 return visit(Expr->getOperand());
404 }
405
406 bool visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
407 return visit(Expr->getOperand());
408 }
409
410 bool visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
411 return visit(Expr->getOperand());
412 }
413
414 bool visitAddExpr(const SCEVAddExpr *Expr) {
415 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
416 if (visit(Expr->getOperand(i)))
417 return true;
418
419 return false;
420 }
421
422 bool visitMulExpr(const SCEVMulExpr *Expr) {
423 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
424 if (visit(Expr->getOperand(i)))
425 return true;
426
427 return false;
428 }
429
430 bool visitUDivExpr(const SCEVUDivExpr *Expr) {
431 if (visit(Expr->getLHS()))
432 return true;
433
434 if (visit(Expr->getRHS()))
435 return true;
436
437 return false;
438 }
439
440 bool visitAddRecExpr(const SCEVAddRecExpr *Expr) {
441 if (visit(Expr->getStart()))
442 return true;
443
444 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
445 if (visit(Expr->getOperand(i)))
446 return true;
447
448 return false;
449 }
450
451 bool visitSMaxExpr(const SCEVSMaxExpr *Expr) {
452 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
453 if (visit(Expr->getOperand(i)))
454 return true;
455
456 return false;
457 }
458
459 bool visitUMaxExpr(const SCEVUMaxExpr *Expr) {
460 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
461 if (visit(Expr->getOperand(i)))
462 return true;
463
464 return false;
465 }
466
467 bool visitUnknown(const SCEVUnknown *Expr) {
468 Instruction *Inst = dyn_cast<Instruction>(Expr->getValue());
469
470 // Return true when Inst is defined inside the region R.
471 if (Inst && R->contains(Inst))
472 return true;
473
474 return false;
475 }
476
477private:
478 const Region *R;
479};
480
Tobias Grosser120db6b2011-11-07 12:58:54 +0000481namespace polly {
Tobias Grossere3c05582014-11-15 21:32:53 +0000482/// Find all loops referenced in SCEVAddRecExprs.
483class SCEVFindLoops {
484 SetVector<const Loop *> &Loops;
485
486public:
487 SCEVFindLoops(SetVector<const Loop *> &Loops) : Loops(Loops) {}
488
489 bool follow(const SCEV *S) {
490 if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S))
491 Loops.insert(AddRec->getLoop());
492 return true;
493 }
494 bool isDone() { return false; }
495};
496
497void findLoops(const SCEV *Expr, SetVector<const Loop *> &Loops) {
498 SCEVFindLoops FindLoops(Loops);
499 SCEVTraversal<SCEVFindLoops> ST(FindLoops);
500 ST.visitAll(Expr);
501}
502
503/// Find all values referenced in SCEVUnknowns.
504class SCEVFindValues {
505 SetVector<Value *> &Values;
506
507public:
508 SCEVFindValues(SetVector<Value *> &Values) : Values(Values) {}
509
510 bool follow(const SCEV *S) {
511 if (const SCEVUnknown *Unknown = dyn_cast<SCEVUnknown>(S))
512 Values.insert(Unknown->getValue());
513 return true;
514 }
515 bool isDone() { return false; }
516};
517
518void findValues(const SCEV *Expr, SetVector<Value *> &Values) {
519 SCEVFindValues FindValues(Values);
520 SCEVTraversal<SCEVFindValues> ST(FindValues);
521 ST.visitAll(Expr);
522}
523
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000524bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R) {
525 return SCEVInRegionDependences::hasDependences(Expr, R);
526}
Sebastian Pop97cb8132013-03-18 20:21:13 +0000527
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000528bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
529 const Value *BaseAddress) {
530 if (isa<SCEVCouldNotCompute>(Expr))
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000531 return false;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000532
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000533 SCEVValidator Validator(R, SE, BaseAddress);
Tobias Grosserf084edd2014-10-22 23:00:03 +0000534 DEBUG({
535 dbgs() << "\n";
536 dbgs() << "Expr: " << *Expr << "\n";
537 dbgs() << "Region: " << R->getNameStr() << "\n";
538 dbgs() << " -> ";
539 });
Tobias Grossereeb776a2012-09-08 14:00:37 +0000540
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000541 ValidatorResult Result = Validator.visit(Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000542
Tobias Grosserf084edd2014-10-22 23:00:03 +0000543 DEBUG({
544 if (Result.isValid())
545 dbgs() << "VALID\n";
546 dbgs() << "\n";
547 });
Tobias Grossereeb776a2012-09-08 14:00:37 +0000548
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000549 return Result.isValid();
550}
Tobias Grosser60b54f12011-11-08 15:41:28 +0000551
Tobias Grossere602a072013-05-07 07:30:56 +0000552std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
553 const SCEV *Expr,
554 ScalarEvolution &SE,
555 const Value *BaseAddress) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000556 if (isa<SCEVCouldNotCompute>(Expr))
557 return std::vector<const SCEV *>();
Tobias Grosser60b54f12011-11-08 15:41:28 +0000558
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000559 SCEVValidator Validator(R, SE, BaseAddress);
560 ValidatorResult Result = Validator.visit(Expr);
Johannes Doerfert89830312015-05-03 16:03:01 +0000561 assert(Result.isValid() && "Requested parameters for an invalid SCEV!");
Tobias Grosser60b54f12011-11-08 15:41:28 +0000562
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000563 return Result.getParameters();
564}
Johannes Doerfertbe409962015-03-29 20:45:09 +0000565
566std::pair<const SCEV *, const SCEV *>
567extractConstantFactor(const SCEV *S, ScalarEvolution &SE) {
568
569 const SCEV *LeftOver = SE.getConstant(S->getType(), 1);
570 const SCEV *ConstPart = SE.getConstant(S->getType(), 1);
571
572 const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S);
573 if (!M)
574 return std::make_pair(ConstPart, S);
575
576 for (const SCEV *Op : M->operands())
577 if (isa<SCEVConstant>(Op))
578 ConstPart = SE.getMulExpr(ConstPart, Op);
579 else
580 LeftOver = SE.getMulExpr(LeftOver, Op);
581
582 return std::make_pair(ConstPart, LeftOver);
583}
Tobias Grosser120db6b2011-11-07 12:58:54 +0000584}