blob: 048fdc32aa119095979cbd10ea4c079a570eb527 [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 Grosser120db6b2011-11-07 12:58:54 +00004#include "llvm/Analysis/ScalarEvolution.h"
5#include "llvm/Analysis/ScalarEvolutionExpressions.h"
6#include "llvm/Analysis/RegionInfo.h"
Chandler Carruth95fef942014-04-22 03:30:19 +00007#include "llvm/Support/Debug.h"
Tobias Grosser120db6b2011-11-07 12:58:54 +00008
Tobias Grosser60b54f12011-11-08 15:41:28 +00009#include <vector>
10
Tobias Grosser120db6b2011-11-07 12:58:54 +000011using namespace llvm;
12
Chandler Carruth95fef942014-04-22 03:30:19 +000013#define DEBUG_TYPE "polly-scev-validator"
14
Tobias Grosser120db6b2011-11-07 12:58:54 +000015namespace SCEVType {
Tobias Grosserde49b8f2013-02-22 08:21:52 +000016/// @brief The type of a SCEV
17///
18/// To check for the validity of a SCEV we assign to each SCEV a type. The
19/// possible types are INT, PARAM, IV and INVALID. The order of the types is
20/// important. The subexpressions of SCEV with a type X can only have a type
21/// that is smaller or equal than X.
22enum TYPE {
23 // An integer value.
24 INT,
Tobias Grosserb1f07c52011-11-17 12:56:17 +000025
Tobias Grosserde49b8f2013-02-22 08:21:52 +000026 // An expression that is constant during the execution of the Scop,
27 // but that may depend on parameters unknown at compile time.
28 PARAM,
Tobias Grosserb1f07c52011-11-17 12:56:17 +000029
Tobias Grosserde49b8f2013-02-22 08:21:52 +000030 // An expression that may change during the execution of the SCoP.
31 IV,
Tobias Grosserb1f07c52011-11-17 12:56:17 +000032
Tobias Grosserde49b8f2013-02-22 08:21:52 +000033 // An invalid expression.
34 INVALID
35};
Tobias Grosser120db6b2011-11-07 12:58:54 +000036}
37
Tobias Grosserb1f07c52011-11-17 12:56:17 +000038/// @brief The result the validator returns for a SCEV expression.
Tobias Grosserfa043f02011-11-17 12:56:19 +000039class ValidatorResult {
Tobias Grosserb1f07c52011-11-17 12:56:17 +000040 /// @brief The type of the expression
Tobias Grosseredb8a282011-11-17 12:56:21 +000041 SCEVType::TYPE Type;
Tobias Grosserb1f07c52011-11-17 12:56:17 +000042
43 /// @brief The set of Parameters in the expression.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000044 std::vector<const SCEV *> Parameters;
Tobias Grosser120db6b2011-11-07 12:58:54 +000045
Tobias Grosserfa043f02011-11-17 12:56:19 +000046public:
Tobias Grosserb1f07c52011-11-17 12:56:17 +000047 /// @brief The copy constructor
Tobias Grosseredb8a282011-11-17 12:56:21 +000048 ValidatorResult(const ValidatorResult &Source) {
49 Type = Source.Type;
50 Parameters = Source.Parameters;
Tobias Grosserde49b8f2013-02-22 08:21:52 +000051 }
Tobias Grosser120db6b2011-11-07 12:58:54 +000052
Tobias Grosserb1f07c52011-11-17 12:56:17 +000053 /// @brief Construct a result with a certain type and no parameters.
Tobias Grosser371bada2012-03-16 10:16:28 +000054 ValidatorResult(SCEVType::TYPE Type) : Type(Type) {
55 assert(Type != SCEVType::PARAM && "Did you forget to pass the parameter");
Tobias Grosserde49b8f2013-02-22 08:21:52 +000056 }
Tobias Grosserb1f07c52011-11-17 12:56:17 +000057
58 /// @brief Construct a result with a certain type and a single parameter.
Tobias Grosseredb8a282011-11-17 12:56:21 +000059 ValidatorResult(SCEVType::TYPE Type, const SCEV *Expr) : Type(Type) {
Tobias Grosser60b54f12011-11-08 15:41:28 +000060 Parameters.push_back(Expr);
Tobias Grosserde49b8f2013-02-22 08:21:52 +000061 }
Tobias Grosser120db6b2011-11-07 12:58:54 +000062
Tobias Grossereeb776a2012-09-08 14:00:37 +000063 /// @brief Get the type of the ValidatorResult.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000064 SCEVType::TYPE getType() { return Type; }
Tobias Grossereeb776a2012-09-08 14:00:37 +000065
Tobias Grosserb1f07c52011-11-17 12:56:17 +000066 /// @brief Is the analyzed SCEV constant during the execution of the SCoP.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000067 bool isConstant() { return Type == SCEVType::INT || Type == SCEVType::PARAM; }
Tobias Grosser120db6b2011-11-07 12:58:54 +000068
Tobias Grosserb1f07c52011-11-17 12:56:17 +000069 /// @brief Is the analyzed SCEV valid.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000070 bool isValid() { return Type != SCEVType::INVALID; }
Tobias Grosser120db6b2011-11-07 12:58:54 +000071
Tobias Grosseredb8a282011-11-17 12:56:21 +000072 /// @brief Is the analyzed SCEV of Type IV.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000073 bool isIV() { return Type == SCEVType::IV; }
Tobias Grosser120db6b2011-11-07 12:58:54 +000074
Tobias Grosseredb8a282011-11-17 12:56:21 +000075 /// @brief Is the analyzed SCEV of Type INT.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000076 bool isINT() { return Type == SCEVType::INT; }
Tobias Grosser60b54f12011-11-08 15:41:28 +000077
Tobias Grossereeb776a2012-09-08 14:00:37 +000078 /// @brief Is the analyzed SCEV of Type PARAM.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000079 bool isPARAM() { return Type == SCEVType::PARAM; }
Tobias Grossereeb776a2012-09-08 14:00:37 +000080
Tobias Grosserfa043f02011-11-17 12:56:19 +000081 /// @brief Get the parameters of this validator result.
Tobias Grosserde49b8f2013-02-22 08:21:52 +000082 std::vector<const SCEV *> getParameters() { return Parameters; }
Tobias Grosserfa043f02011-11-17 12:56:19 +000083
Tobias Grosserb1f07c52011-11-17 12:56:17 +000084 /// @brief Add the parameters of Source to this result.
Johannes Doerfertecc33a12015-02-26 19:33:42 +000085 void addParamsFrom(const ValidatorResult &Source) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +000086 Parameters.insert(Parameters.end(), Source.Parameters.begin(),
Tobias Grosser60b54f12011-11-08 15:41:28 +000087 Source.Parameters.end());
88 }
Tobias Grosserfa043f02011-11-17 12:56:19 +000089
90 /// @brief Merge a result.
91 ///
Tobias Grosseredb8a282011-11-17 12:56:21 +000092 /// This means to merge the parameters and to set the Type to the most
93 /// specific Type that matches both.
Johannes Doerfertecc33a12015-02-26 19:33:42 +000094 void merge(const ValidatorResult &ToMerge) {
Tobias Grosseredb8a282011-11-17 12:56:21 +000095 Type = std::max(Type, ToMerge.Type);
Tobias Grosserfa043f02011-11-17 12:56:19 +000096 addParamsFrom(ToMerge);
97 }
Tobias Grosser540757b2012-03-16 10:12:37 +000098
99 void print(raw_ostream &OS) {
100 switch (Type) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000101 case SCEVType::INT:
102 OS << "SCEVType::INT";
Tobias Grosser540757b2012-03-16 10:12:37 +0000103 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000104 case SCEVType::PARAM:
105 OS << "SCEVType::PARAM";
Tobias Grosser540757b2012-03-16 10:12:37 +0000106 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000107 case SCEVType::IV:
108 OS << "SCEVType::IV";
Tobias Grosser540757b2012-03-16 10:12:37 +0000109 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000110 case SCEVType::INVALID:
111 OS << "SCEVType::INVALID";
Tobias Grosser540757b2012-03-16 10:12:37 +0000112 break;
113 }
114 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000115};
116
Tobias Grosser540757b2012-03-16 10:12:37 +0000117raw_ostream &operator<<(raw_ostream &OS, class ValidatorResult &VR) {
118 VR.print(OS);
119 return OS;
120}
121
Tobias Grosser120db6b2011-11-07 12:58:54 +0000122/// Check if a SCEV is valid in a SCoP.
Tobias Grosser58032cb2013-06-23 01:29:29 +0000123struct SCEVValidator
124 : public SCEVVisitor<SCEVValidator, class ValidatorResult> {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000125private:
126 const Region *R;
127 ScalarEvolution &SE;
Tobias Grossere5e171e2011-11-10 12:45:03 +0000128 const Value *BaseAddress;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000129
130public:
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000131 SCEVValidator(const Region *R, ScalarEvolution &SE, const Value *BaseAddress)
132 : R(R), SE(SE), BaseAddress(BaseAddress) {}
Tobias Grosser120db6b2011-11-07 12:58:54 +0000133
Tobias Grosserfa043f02011-11-17 12:56:19 +0000134 class ValidatorResult visitConstant(const SCEVConstant *Constant) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000135 return ValidatorResult(SCEVType::INT);
136 }
137
Tobias Grosserfa043f02011-11-17 12:56:19 +0000138 class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000139 ValidatorResult Op = visit(Expr->getOperand());
140
Tobias Grossereeb776a2012-09-08 14:00:37 +0000141 switch (Op.getType()) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000142 case SCEVType::INT:
143 case SCEVType::PARAM:
144 // We currently do not represent a truncate expression as an affine
145 // expression. If it is constant during Scop execution, we treat it as a
146 // parameter.
147 return ValidatorResult(SCEVType::PARAM, Expr);
148 case SCEVType::IV:
149 DEBUG(dbgs() << "INVALID: Truncation of SCEVType::IV expression");
150 return ValidatorResult(SCEVType::INVALID);
151 case SCEVType::INVALID:
152 return Op;
Tobias Grossereeb776a2012-09-08 14:00:37 +0000153 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000154
Tobias Grossereeb776a2012-09-08 14:00:37 +0000155 llvm_unreachable("Unknown SCEVType");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000156 }
157
Tobias Grosserfa043f02011-11-17 12:56:19 +0000158 class ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
Tobias Grosserf4daf342014-08-16 09:08:55 +0000159 ValidatorResult Op = visit(Expr->getOperand());
Tobias Grosser120db6b2011-11-07 12:58:54 +0000160
Tobias Grossereeb776a2012-09-08 14:00:37 +0000161 switch (Op.getType()) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000162 case SCEVType::INT:
163 case SCEVType::PARAM:
164 // We currently do not represent a truncate expression as an affine
165 // expression. If it is constant during Scop execution, we treat it as a
166 // parameter.
167 return ValidatorResult(SCEVType::PARAM, Expr);
168 case SCEVType::IV:
169 DEBUG(dbgs() << "INVALID: ZeroExtend of SCEVType::IV expression");
170 return ValidatorResult(SCEVType::INVALID);
171 case SCEVType::INVALID:
172 return Op;
Tobias Grossereeb776a2012-09-08 14:00:37 +0000173 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000174
Tobias Grossereeb776a2012-09-08 14:00:37 +0000175 llvm_unreachable("Unknown SCEVType");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000176 }
177
Tobias Grosserfa043f02011-11-17 12:56:19 +0000178 class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000179 // We currently allow only signed SCEV expressions. In the case of a
180 // signed value, a sign extend is a noop.
181 //
182 // TODO: Reconsider this when we add support for unsigned values.
183 return visit(Expr->getOperand());
184 }
185
Tobias Grosserfa043f02011-11-17 12:56:19 +0000186 class ValidatorResult visitAddExpr(const SCEVAddExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000187 ValidatorResult Return(SCEVType::INT);
188
189 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
190 ValidatorResult Op = visit(Expr->getOperand(i));
Tobias Grosserfa043f02011-11-17 12:56:19 +0000191 Return.merge(Op);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000192
193 // Early exit.
194 if (!Return.isValid())
195 break;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000196 }
197
198 // TODO: Check for NSW and NUW.
199 return Return;
200 }
201
Tobias Grosserfa043f02011-11-17 12:56:19 +0000202 class ValidatorResult visitMulExpr(const SCEVMulExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000203 ValidatorResult Return(SCEVType::INT);
204
Tobias Grosser3ed26002013-04-14 13:15:59 +0000205 bool HasMultipleParams = false;
206
Tobias Grosser120db6b2011-11-07 12:58:54 +0000207 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
208 ValidatorResult Op = visit(Expr->getOperand(i));
209
Tobias Grosserfa043f02011-11-17 12:56:19 +0000210 if (Op.isINT())
Tobias Grosser120db6b2011-11-07 12:58:54 +0000211 continue;
212
Tobias Grosserecb50922013-04-10 07:42:28 +0000213 if (Op.isPARAM() && Return.isPARAM()) {
Tobias Grossere602a072013-05-07 07:30:56 +0000214 HasMultipleParams = true;
Tobias Grosserecb50922013-04-10 07:42:28 +0000215 continue;
216 }
217
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000218 if ((Op.isIV() || Op.isPARAM()) && !Return.isINT()) {
Tobias Grossereeb776a2012-09-08 14:00:37 +0000219 DEBUG(dbgs() << "INVALID: More than one non-int operand in MulExpr\n"
220 << "\tExpr: " << *Expr << "\n"
221 << "\tPrevious expression type: " << Return << "\n"
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000222 << "\tNext operand (" << Op
223 << "): " << *Expr->getOperand(i) << "\n");
Tobias Grossereeb776a2012-09-08 14:00:37 +0000224
Tobias Grosser120db6b2011-11-07 12:58:54 +0000225 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000226 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000227
Tobias Grosserfa043f02011-11-17 12:56:19 +0000228 Return.merge(Op);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000229 }
230
Tobias Grosser3ed26002013-04-14 13:15:59 +0000231 if (HasMultipleParams)
232 return ValidatorResult(SCEVType::PARAM, Expr);
233
Tobias Grosser120db6b2011-11-07 12:58:54 +0000234 // TODO: Check for NSW and NUW.
235 return Return;
236 }
237
Tobias Grosserfa043f02011-11-17 12:56:19 +0000238 class ValidatorResult visitUDivExpr(const SCEVUDivExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000239 ValidatorResult LHS = visit(Expr->getLHS());
240 ValidatorResult RHS = visit(Expr->getRHS());
241
Tobias Grosserf9fbbdf2012-04-09 19:46:05 +0000242 // We currently do not represent an unsigned division as an affine
Tobias Grosser120db6b2011-11-07 12:58:54 +0000243 // expression. If the division is constant during Scop execution we treat it
244 // as a parameter, otherwise we bail out.
245 if (LHS.isConstant() && RHS.isConstant())
Tobias Grosser60b54f12011-11-08 15:41:28 +0000246 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000247
Tobias Grossereeb776a2012-09-08 14:00:37 +0000248 DEBUG(dbgs() << "INVALID: unsigned division of non-constant expressions");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000249 return ValidatorResult(SCEVType::INVALID);
250 }
251
Tobias Grosserfa043f02011-11-17 12:56:19 +0000252 class ValidatorResult visitAddRecExpr(const SCEVAddRecExpr *Expr) {
Tobias Grossereeb776a2012-09-08 14:00:37 +0000253 if (!Expr->isAffine()) {
254 DEBUG(dbgs() << "INVALID: AddRec is not affine");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000255 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000256 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000257
258 ValidatorResult Start = visit(Expr->getStart());
259 ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE));
260
Tobias Grossereeb776a2012-09-08 14:00:37 +0000261 if (!Start.isValid())
262 return Start;
263
264 if (!Recurrence.isValid())
265 return Recurrence;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000266
Tobias Grosserbcc0a0d2011-11-17 12:56:14 +0000267 if (R->contains(Expr->getLoop())) {
268 if (Recurrence.isINT()) {
269 ValidatorResult Result(SCEVType::IV);
270 Result.addParamsFrom(Start);
271 return Result;
272 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000273
Tobias Grossereeb776a2012-09-08 14:00:37 +0000274 DEBUG(dbgs() << "INVALID: AddRec within scop has non-int"
275 "recurrence part");
Tobias Grosserbcc0a0d2011-11-17 12:56:14 +0000276 return ValidatorResult(SCEVType::INVALID);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000277 }
278
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000279 assert(Start.isConstant() && Recurrence.isConstant() &&
280 "Expected 'Start' and 'Recurrence' to be constant");
Tobias Grossere42ddb92013-08-05 15:14:15 +0000281
282 // Directly generate ValidatorResult for Expr if 'start' is zero.
283 if (Expr->getStart()->isZero())
284 return ValidatorResult(SCEVType::PARAM, Expr);
285
286 // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
287 // if 'start' is not zero.
288 const SCEV *ZeroStartExpr = SE.getAddRecExpr(
289 SE.getConstant(Expr->getStart()->getType(), 0),
290 Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
291
292 ValidatorResult ZeroStartResult =
293 ValidatorResult(SCEVType::PARAM, ZeroStartExpr);
294 ZeroStartResult.addParamsFrom(Start);
295
296 return ZeroStartResult;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000297 }
298
Tobias Grosserfa043f02011-11-17 12:56:19 +0000299 class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) {
Tobias Grosser7b6f9ba2013-12-09 21:51:46 +0000300 ValidatorResult Return(SCEVType::INT);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000301
302 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
303 ValidatorResult Op = visit(Expr->getOperand(i));
304
305 if (!Op.isValid())
Tobias Grossereeb776a2012-09-08 14:00:37 +0000306 return Op;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000307
Tobias Grosserfa043f02011-11-17 12:56:19 +0000308 Return.merge(Op);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000309 }
310
311 return Return;
312 }
313
Tobias Grosserfa043f02011-11-17 12:56:19 +0000314 class ValidatorResult visitUMaxExpr(const SCEVUMaxExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000315 // We do not support unsigned operations. If 'Expr' is constant during Scop
316 // execution we treat this as a parameter, otherwise we bail out.
317 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
318 ValidatorResult Op = visit(Expr->getOperand(i));
319
Tobias Grossereeb776a2012-09-08 14:00:37 +0000320 if (!Op.isConstant()) {
321 DEBUG(dbgs() << "INVALID: UMaxExpr has a non-constant operand");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000322 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000323 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000324 }
325
Tobias Grosser371bada2012-03-16 10:16:28 +0000326 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000327 }
328
Johannes Doerfertb9d18882015-02-11 14:54:50 +0000329 ValidatorResult visitGenericInst(Instruction *I, const SCEV *S) {
330 if (R->contains(I)) {
331 DEBUG(dbgs() << "INVALID: UnknownExpr references an instruction "
332 "within the region\n");
333 return ValidatorResult(SCEVType::INVALID);
334 }
335
336 return ValidatorResult(SCEVType::PARAM, S);
337 }
338
339 ValidatorResult visitSDivInstruction(Instruction *SDiv, const SCEV *S) {
340 assert(SDiv->getOpcode() == Instruction::SDiv &&
341 "Assumed SDiv instruction!");
342
343 auto *Divisor = SDiv->getOperand(1);
344 auto *CI = dyn_cast<ConstantInt>(Divisor);
345 if (!CI)
346 return visitGenericInst(SDiv, S);
347
348 auto *Dividend = SDiv->getOperand(0);
349 auto *DividendSCEV = SE.getSCEV(Dividend);
350 return visit(DividendSCEV);
351 }
352
Tobias Grosser7ffe4e82011-11-17 12:56:10 +0000353 ValidatorResult visitUnknown(const SCEVUnknown *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000354 Value *V = Expr->getValue();
355
Tobias Grosser55bc4c02015-01-08 19:26:53 +0000356 if (!(Expr->getType()->isIntegerTy() || Expr->getType()->isPointerTy())) {
357 DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer or pointer type");
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000358 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000359 }
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000360
Tobias Grossereeb776a2012-09-08 14:00:37 +0000361 if (isa<UndefValue>(V)) {
362 DEBUG(dbgs() << "INVALID: UnknownExpr references an undef value");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000363 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000364 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000365
Tobias Grossereeb776a2012-09-08 14:00:37 +0000366 if (BaseAddress == V) {
367 DEBUG(dbgs() << "INVALID: UnknownExpr references BaseAddress\n");
Tobias Grossere5e171e2011-11-10 12:45:03 +0000368 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000369 }
Tobias Grossere5e171e2011-11-10 12:45:03 +0000370
Johannes Doerfertb9d18882015-02-11 14:54:50 +0000371 if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) {
372 switch (I->getOpcode()) {
373 case Instruction::SDiv:
374 return visitSDivInstruction(I, Expr);
375 default:
376 return visitGenericInst(I, Expr);
377 }
378 }
379
Tobias Grossere5e171e2011-11-10 12:45:03 +0000380 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000381 }
382};
383
Sebastian Pop97cb8132013-03-18 20:21:13 +0000384/// @brief Check whether a SCEV refers to an SSA name defined inside a region.
385///
Tobias Grosser58032cb2013-06-23 01:29:29 +0000386struct SCEVInRegionDependences
387 : public SCEVVisitor<SCEVInRegionDependences, bool> {
Sebastian Pop97cb8132013-03-18 20:21:13 +0000388public:
Sebastian Pop97cb8132013-03-18 20:21:13 +0000389 /// Returns true when the SCEV has SSA names defined in region R.
390 static bool hasDependences(const SCEV *S, const Region *R) {
391 SCEVInRegionDependences Ignore(R);
392 return Ignore.visit(S);
393 }
394
395 SCEVInRegionDependences(const Region *R) : R(R) {}
396
397 bool visit(const SCEV *Expr) {
398 return SCEVVisitor<SCEVInRegionDependences, bool>::visit(Expr);
399 }
400
401 bool visitConstant(const SCEVConstant *Constant) { return false; }
402
403 bool visitTruncateExpr(const SCEVTruncateExpr *Expr) {
404 return visit(Expr->getOperand());
405 }
406
407 bool visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
408 return visit(Expr->getOperand());
409 }
410
411 bool visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
412 return visit(Expr->getOperand());
413 }
414
415 bool visitAddExpr(const SCEVAddExpr *Expr) {
416 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
417 if (visit(Expr->getOperand(i)))
418 return true;
419
420 return false;
421 }
422
423 bool visitMulExpr(const SCEVMulExpr *Expr) {
424 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
425 if (visit(Expr->getOperand(i)))
426 return true;
427
428 return false;
429 }
430
431 bool visitUDivExpr(const SCEVUDivExpr *Expr) {
432 if (visit(Expr->getLHS()))
433 return true;
434
435 if (visit(Expr->getRHS()))
436 return true;
437
438 return false;
439 }
440
441 bool visitAddRecExpr(const SCEVAddRecExpr *Expr) {
442 if (visit(Expr->getStart()))
443 return true;
444
445 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
446 if (visit(Expr->getOperand(i)))
447 return true;
448
449 return false;
450 }
451
452 bool visitSMaxExpr(const SCEVSMaxExpr *Expr) {
453 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
454 if (visit(Expr->getOperand(i)))
455 return true;
456
457 return false;
458 }
459
460 bool visitUMaxExpr(const SCEVUMaxExpr *Expr) {
461 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
462 if (visit(Expr->getOperand(i)))
463 return true;
464
465 return false;
466 }
467
468 bool visitUnknown(const SCEVUnknown *Expr) {
469 Instruction *Inst = dyn_cast<Instruction>(Expr->getValue());
470
471 // Return true when Inst is defined inside the region R.
472 if (Inst && R->contains(Inst))
473 return true;
474
475 return false;
476 }
477
478private:
479 const Region *R;
480};
481
Tobias Grosser120db6b2011-11-07 12:58:54 +0000482namespace polly {
Tobias Grossere3c05582014-11-15 21:32:53 +0000483/// Find all loops referenced in SCEVAddRecExprs.
484class SCEVFindLoops {
485 SetVector<const Loop *> &Loops;
486
487public:
488 SCEVFindLoops(SetVector<const Loop *> &Loops) : Loops(Loops) {}
489
490 bool follow(const SCEV *S) {
491 if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S))
492 Loops.insert(AddRec->getLoop());
493 return true;
494 }
495 bool isDone() { return false; }
496};
497
498void findLoops(const SCEV *Expr, SetVector<const Loop *> &Loops) {
499 SCEVFindLoops FindLoops(Loops);
500 SCEVTraversal<SCEVFindLoops> ST(FindLoops);
501 ST.visitAll(Expr);
502}
503
504/// Find all values referenced in SCEVUnknowns.
505class SCEVFindValues {
506 SetVector<Value *> &Values;
507
508public:
509 SCEVFindValues(SetVector<Value *> &Values) : Values(Values) {}
510
511 bool follow(const SCEV *S) {
512 if (const SCEVUnknown *Unknown = dyn_cast<SCEVUnknown>(S))
513 Values.insert(Unknown->getValue());
514 return true;
515 }
516 bool isDone() { return false; }
517};
518
519void findValues(const SCEV *Expr, SetVector<Value *> &Values) {
520 SCEVFindValues FindValues(Values);
521 SCEVTraversal<SCEVFindValues> ST(FindValues);
522 ST.visitAll(Expr);
523}
524
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000525bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R) {
526 return SCEVInRegionDependences::hasDependences(Expr, R);
527}
Sebastian Pop97cb8132013-03-18 20:21:13 +0000528
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000529bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
530 const Value *BaseAddress) {
531 if (isa<SCEVCouldNotCompute>(Expr))
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000532 return false;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000533
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000534 SCEVValidator Validator(R, SE, BaseAddress);
Tobias Grosserf084edd2014-10-22 23:00:03 +0000535 DEBUG({
536 dbgs() << "\n";
537 dbgs() << "Expr: " << *Expr << "\n";
538 dbgs() << "Region: " << R->getNameStr() << "\n";
539 dbgs() << " -> ";
540 });
Tobias Grossereeb776a2012-09-08 14:00:37 +0000541
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000542 ValidatorResult Result = Validator.visit(Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000543
Tobias Grosserf084edd2014-10-22 23:00:03 +0000544 DEBUG({
545 if (Result.isValid())
546 dbgs() << "VALID\n";
547 dbgs() << "\n";
548 });
Tobias Grossereeb776a2012-09-08 14:00:37 +0000549
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000550 return Result.isValid();
551}
Tobias Grosser60b54f12011-11-08 15:41:28 +0000552
Tobias Grossere602a072013-05-07 07:30:56 +0000553std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
554 const SCEV *Expr,
555 ScalarEvolution &SE,
556 const Value *BaseAddress) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000557 if (isa<SCEVCouldNotCompute>(Expr))
558 return std::vector<const SCEV *>();
Tobias Grosser60b54f12011-11-08 15:41:28 +0000559
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000560 SCEVValidator Validator(R, SE, BaseAddress);
561 ValidatorResult Result = Validator.visit(Expr);
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}