blob: e11c9e09fcf140c6b0ca56215f986377b6de5305 [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 Doerfert5130c842014-08-15 01:14:11 +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 Doerfert5130c842014-08-15 01:14:11 +000094 ValidatorResult &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);
Johannes Doerfert5130c842014-08-15 01:14:11 +000097 return *this;
Tobias Grosserfa043f02011-11-17 12:56:19 +000098 }
Tobias Grosser540757b2012-03-16 10:12:37 +000099
100 void print(raw_ostream &OS) {
101 switch (Type) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000102 case SCEVType::INT:
103 OS << "SCEVType::INT";
Tobias Grosser540757b2012-03-16 10:12:37 +0000104 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000105 case SCEVType::PARAM:
106 OS << "SCEVType::PARAM";
Tobias Grosser540757b2012-03-16 10:12:37 +0000107 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000108 case SCEVType::IV:
109 OS << "SCEVType::IV";
Tobias Grosser540757b2012-03-16 10:12:37 +0000110 break;
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000111 case SCEVType::INVALID:
112 OS << "SCEVType::INVALID";
Tobias Grosser540757b2012-03-16 10:12:37 +0000113 break;
114 }
115 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000116};
117
Tobias Grosser540757b2012-03-16 10:12:37 +0000118raw_ostream &operator<<(raw_ostream &OS, class ValidatorResult &VR) {
119 VR.print(OS);
120 return OS;
121}
122
Tobias Grosser120db6b2011-11-07 12:58:54 +0000123/// Check if a SCEV is valid in a SCoP.
Tobias Grosser58032cb2013-06-23 01:29:29 +0000124struct SCEVValidator
125 : public SCEVVisitor<SCEVValidator, class ValidatorResult> {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000126private:
127 const Region *R;
128 ScalarEvolution &SE;
Tobias Grossere5e171e2011-11-10 12:45:03 +0000129 const Value *BaseAddress;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000130
131public:
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000132 SCEVValidator(const Region *R, ScalarEvolution &SE, const Value *BaseAddress)
133 : R(R), SE(SE), BaseAddress(BaseAddress) {}
Tobias Grosser120db6b2011-11-07 12:58:54 +0000134
Tobias Grosserfa043f02011-11-17 12:56:19 +0000135 class ValidatorResult visitConstant(const SCEVConstant *Constant) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000136 return ValidatorResult(SCEVType::INT);
137 }
138
Tobias Grosserfa043f02011-11-17 12:56:19 +0000139 class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000140 ValidatorResult Op = visit(Expr->getOperand());
141
Tobias Grossereeb776a2012-09-08 14:00:37 +0000142 switch (Op.getType()) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000143 case SCEVType::INT:
144 case SCEVType::PARAM:
145 // We currently do not represent a truncate expression as an affine
146 // expression. If it is constant during Scop execution, we treat it as a
147 // parameter.
148 return ValidatorResult(SCEVType::PARAM, Expr);
149 case SCEVType::IV:
150 DEBUG(dbgs() << "INVALID: Truncation of SCEVType::IV expression");
151 return ValidatorResult(SCEVType::INVALID);
152 case SCEVType::INVALID:
153 return Op;
Tobias Grossereeb776a2012-09-08 14:00:37 +0000154 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000155
Tobias Grossereeb776a2012-09-08 14:00:37 +0000156 llvm_unreachable("Unknown SCEVType");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000157 }
158
Tobias Grosserfa043f02011-11-17 12:56:19 +0000159 class ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000160
Johannes Doerfert5130c842014-08-15 01:14:11 +0000161 // Pattern matching rules to capture some bit and modulo computations:
162 //
163 // EXP % 2^C <==>
164 // [A] (i + c) & (2^C - 1) ==> zext iC {c,+,1}<%for_i> to IXX
165 // [B] (p + q) & (2^C - 1) ==> zext iC (trunc iXX %p_add_q to iC) to iXX
166 // [C] (i + p) & (2^C - 1) ==> zext iC {p & (2^C - 1),+,1}<%for_i> to iXX
167 // ==> zext iC {trunc iXX %p to iC,+,1}<%for_i> to
168
169 // Check for [A] and [C].
170 const SCEV *OpS = Expr->getOperand();
171 if (auto *OpAR = dyn_cast<SCEVAddRecExpr>(OpS)) {
172 const SCEV *OpARStart = OpAR->getStart();
173
174 // Special case for [C].
175 if (auto *OpARStartTR = dyn_cast<SCEVTruncateExpr>(OpARStart))
176 OpARStart = OpARStartTR->getOperand();
177
178 ValidatorResult OpARStartVR = visit(OpARStart);
179 if (OpARStartVR.isConstant() && OpAR->getStepRecurrence(SE)->isOne())
180 return OpARStartVR;
181 }
182
183 // Check for [B].
184 if (auto *OpTR = dyn_cast<SCEVTruncateExpr>(OpS)) {
185 ValidatorResult OpTRVR = visit(OpTR->getOperand());
186 if (OpTRVR.isConstant())
187 return OpTRVR;
188 }
189
190 ValidatorResult Op = visit(OpS);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000191 switch (Op.getType()) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000192 case SCEVType::INT:
193 case SCEVType::PARAM:
194 // We currently do not represent a truncate expression as an affine
195 // expression. If it is constant during Scop execution, we treat it as a
196 // parameter.
197 return ValidatorResult(SCEVType::PARAM, Expr);
198 case SCEVType::IV:
199 DEBUG(dbgs() << "INVALID: ZeroExtend of SCEVType::IV expression");
200 return ValidatorResult(SCEVType::INVALID);
201 case SCEVType::INVALID:
202 return Op;
Tobias Grossereeb776a2012-09-08 14:00:37 +0000203 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000204
Tobias Grossereeb776a2012-09-08 14:00:37 +0000205 llvm_unreachable("Unknown SCEVType");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000206 }
207
Tobias Grosserfa043f02011-11-17 12:56:19 +0000208 class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000209 // We currently allow only signed SCEV expressions. In the case of a
210 // signed value, a sign extend is a noop.
211 //
212 // TODO: Reconsider this when we add support for unsigned values.
213 return visit(Expr->getOperand());
214 }
215
Tobias Grosserfa043f02011-11-17 12:56:19 +0000216 class ValidatorResult visitAddExpr(const SCEVAddExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000217 ValidatorResult Return(SCEVType::INT);
218
219 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
220 ValidatorResult Op = visit(Expr->getOperand(i));
Tobias Grosserfa043f02011-11-17 12:56:19 +0000221 Return.merge(Op);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000222
223 // Early exit.
224 if (!Return.isValid())
225 break;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000226 }
227
228 // TODO: Check for NSW and NUW.
229 return Return;
230 }
231
Tobias Grosserfa043f02011-11-17 12:56:19 +0000232 class ValidatorResult visitMulExpr(const SCEVMulExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000233 ValidatorResult Return(SCEVType::INT);
234
Tobias Grosser3ed26002013-04-14 13:15:59 +0000235 bool HasMultipleParams = false;
236
Tobias Grosser120db6b2011-11-07 12:58:54 +0000237 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
238 ValidatorResult Op = visit(Expr->getOperand(i));
239
Tobias Grosserfa043f02011-11-17 12:56:19 +0000240 if (Op.isINT())
Tobias Grosser120db6b2011-11-07 12:58:54 +0000241 continue;
242
Tobias Grosserecb50922013-04-10 07:42:28 +0000243 if (Op.isPARAM() && Return.isPARAM()) {
Tobias Grossere602a072013-05-07 07:30:56 +0000244 HasMultipleParams = true;
Tobias Grosserecb50922013-04-10 07:42:28 +0000245 continue;
246 }
247
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000248 if ((Op.isIV() || Op.isPARAM()) && !Return.isINT()) {
Tobias Grossereeb776a2012-09-08 14:00:37 +0000249 DEBUG(dbgs() << "INVALID: More than one non-int operand in MulExpr\n"
250 << "\tExpr: " << *Expr << "\n"
251 << "\tPrevious expression type: " << Return << "\n"
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000252 << "\tNext operand (" << Op
253 << "): " << *Expr->getOperand(i) << "\n");
Tobias Grossereeb776a2012-09-08 14:00:37 +0000254
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
Tobias Grosserfa043f02011-11-17 12:56:19 +0000258 Return.merge(Op);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000259 }
260
Tobias Grosser3ed26002013-04-14 13:15:59 +0000261 if (HasMultipleParams)
262 return ValidatorResult(SCEVType::PARAM, Expr);
263
Tobias Grosser120db6b2011-11-07 12:58:54 +0000264 // TODO: Check for NSW and NUW.
265 return Return;
266 }
267
Tobias Grosserfa043f02011-11-17 12:56:19 +0000268 class ValidatorResult visitUDivExpr(const SCEVUDivExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000269 ValidatorResult LHS = visit(Expr->getLHS());
270 ValidatorResult RHS = visit(Expr->getRHS());
271
Tobias Grosserf9fbbdf2012-04-09 19:46:05 +0000272 // We currently do not represent an unsigned division as an affine
Tobias Grosser120db6b2011-11-07 12:58:54 +0000273 // expression. If the division is constant during Scop execution we treat it
274 // as a parameter, otherwise we bail out.
275 if (LHS.isConstant() && RHS.isConstant())
Tobias Grosser60b54f12011-11-08 15:41:28 +0000276 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000277
Tobias Grossereeb776a2012-09-08 14:00:37 +0000278 DEBUG(dbgs() << "INVALID: unsigned division of non-constant expressions");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000279 return ValidatorResult(SCEVType::INVALID);
280 }
281
Tobias Grosserfa043f02011-11-17 12:56:19 +0000282 class ValidatorResult visitAddRecExpr(const SCEVAddRecExpr *Expr) {
Tobias Grossereeb776a2012-09-08 14:00:37 +0000283 if (!Expr->isAffine()) {
284 DEBUG(dbgs() << "INVALID: AddRec is not affine");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000285 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000286 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000287
288 ValidatorResult Start = visit(Expr->getStart());
289 ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE));
290
Tobias Grossereeb776a2012-09-08 14:00:37 +0000291 if (!Start.isValid())
292 return Start;
293
294 if (!Recurrence.isValid())
295 return Recurrence;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000296
Tobias Grosserbcc0a0d2011-11-17 12:56:14 +0000297 if (R->contains(Expr->getLoop())) {
298 if (Recurrence.isINT()) {
299 ValidatorResult Result(SCEVType::IV);
300 Result.addParamsFrom(Start);
301 return Result;
302 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000303
Tobias Grossereeb776a2012-09-08 14:00:37 +0000304 DEBUG(dbgs() << "INVALID: AddRec within scop has non-int"
305 "recurrence part");
Tobias Grosserbcc0a0d2011-11-17 12:56:14 +0000306 return ValidatorResult(SCEVType::INVALID);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000307 }
308
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000309 assert(Start.isConstant() && Recurrence.isConstant() &&
310 "Expected 'Start' and 'Recurrence' to be constant");
Tobias Grossere42ddb92013-08-05 15:14:15 +0000311
312 // Directly generate ValidatorResult for Expr if 'start' is zero.
313 if (Expr->getStart()->isZero())
314 return ValidatorResult(SCEVType::PARAM, Expr);
315
316 // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
317 // if 'start' is not zero.
318 const SCEV *ZeroStartExpr = SE.getAddRecExpr(
319 SE.getConstant(Expr->getStart()->getType(), 0),
320 Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
321
322 ValidatorResult ZeroStartResult =
323 ValidatorResult(SCEVType::PARAM, ZeroStartExpr);
324 ZeroStartResult.addParamsFrom(Start);
325
326 return ZeroStartResult;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000327 }
328
Tobias Grosserfa043f02011-11-17 12:56:19 +0000329 class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) {
Tobias Grosser7b6f9ba2013-12-09 21:51:46 +0000330 ValidatorResult Return(SCEVType::INT);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000331
332 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
333 ValidatorResult Op = visit(Expr->getOperand(i));
334
335 if (!Op.isValid())
Tobias Grossereeb776a2012-09-08 14:00:37 +0000336 return Op;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000337
Tobias Grosserfa043f02011-11-17 12:56:19 +0000338 Return.merge(Op);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000339 }
340
341 return Return;
342 }
343
Tobias Grosserfa043f02011-11-17 12:56:19 +0000344 class ValidatorResult visitUMaxExpr(const SCEVUMaxExpr *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000345 // We do not support unsigned operations. If 'Expr' is constant during Scop
346 // execution we treat this as a parameter, otherwise we bail out.
347 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
348 ValidatorResult Op = visit(Expr->getOperand(i));
349
Tobias Grossereeb776a2012-09-08 14:00:37 +0000350 if (!Op.isConstant()) {
351 DEBUG(dbgs() << "INVALID: UMaxExpr has a non-constant operand");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000352 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000353 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000354 }
355
Tobias Grosser371bada2012-03-16 10:16:28 +0000356 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000357 }
358
Tobias Grosser7ffe4e82011-11-17 12:56:10 +0000359 ValidatorResult visitUnknown(const SCEVUnknown *Expr) {
Tobias Grosser120db6b2011-11-07 12:58:54 +0000360 Value *V = Expr->getValue();
361
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000362 // We currently only support integer types. It may be useful to support
363 // pointer types, e.g. to support code like:
364 //
365 // if (A)
366 // A[i] = 1;
367 //
368 // See test/CodeGen/20120316-InvalidCast.ll
Tobias Grossereeb776a2012-09-08 14:00:37 +0000369 if (!Expr->getType()->isIntegerTy()) {
370 DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer type");
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000371 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000372 }
Tobias Grosser3ec2abc2012-03-16 16:36:47 +0000373
Tobias Grossereeb776a2012-09-08 14:00:37 +0000374 if (isa<UndefValue>(V)) {
375 DEBUG(dbgs() << "INVALID: UnknownExpr references an undef value");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000376 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000377 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000378
Johannes Doerfert5130c842014-08-15 01:14:11 +0000379 if (auto *I = dyn_cast<Instruction>(Expr->getValue())) {
380 if (I->getOpcode() == Instruction::SRem) {
381
382 ValidatorResult Op0 = visit(SE.getSCEV(I->getOperand(0)));
383 if (!Op0.isValid())
384 return ValidatorResult(SCEVType::INVALID);
385
386 ValidatorResult Op1 = visit(SE.getSCEV(I->getOperand(1)));
387 if (!Op1.isValid() || !Op1.isINT())
388 return ValidatorResult(SCEVType::INVALID);
389
390 Op0.merge(Op1);
391 return Op0;
392 }
393
Tobias Grossereeb776a2012-09-08 14:00:37 +0000394 if (R->contains(I)) {
395 DEBUG(dbgs() << "INVALID: UnknownExpr references an instruction "
396 "within the region\n");
Tobias Grosser120db6b2011-11-07 12:58:54 +0000397 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000398 }
Johannes Doerfert5130c842014-08-15 01:14:11 +0000399 }
Tobias Grosser120db6b2011-11-07 12:58:54 +0000400
Tobias Grossereeb776a2012-09-08 14:00:37 +0000401 if (BaseAddress == V) {
402 DEBUG(dbgs() << "INVALID: UnknownExpr references BaseAddress\n");
Tobias Grossere5e171e2011-11-10 12:45:03 +0000403 return ValidatorResult(SCEVType::INVALID);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000404 }
Tobias Grossere5e171e2011-11-10 12:45:03 +0000405
406 return ValidatorResult(SCEVType::PARAM, Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000407 }
408};
409
Sebastian Pop97cb8132013-03-18 20:21:13 +0000410/// @brief Check whether a SCEV refers to an SSA name defined inside a region.
411///
Tobias Grosser58032cb2013-06-23 01:29:29 +0000412struct SCEVInRegionDependences
413 : public SCEVVisitor<SCEVInRegionDependences, bool> {
Sebastian Pop97cb8132013-03-18 20:21:13 +0000414public:
Sebastian Pop97cb8132013-03-18 20:21:13 +0000415 /// Returns true when the SCEV has SSA names defined in region R.
416 static bool hasDependences(const SCEV *S, const Region *R) {
417 SCEVInRegionDependences Ignore(R);
418 return Ignore.visit(S);
419 }
420
421 SCEVInRegionDependences(const Region *R) : R(R) {}
422
423 bool visit(const SCEV *Expr) {
424 return SCEVVisitor<SCEVInRegionDependences, bool>::visit(Expr);
425 }
426
427 bool visitConstant(const SCEVConstant *Constant) { return false; }
428
429 bool visitTruncateExpr(const SCEVTruncateExpr *Expr) {
430 return visit(Expr->getOperand());
431 }
432
433 bool visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
434 return visit(Expr->getOperand());
435 }
436
437 bool visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
438 return visit(Expr->getOperand());
439 }
440
441 bool visitAddExpr(const SCEVAddExpr *Expr) {
442 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
443 if (visit(Expr->getOperand(i)))
444 return true;
445
446 return false;
447 }
448
449 bool visitMulExpr(const SCEVMulExpr *Expr) {
450 for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
451 if (visit(Expr->getOperand(i)))
452 return true;
453
454 return false;
455 }
456
457 bool visitUDivExpr(const SCEVUDivExpr *Expr) {
458 if (visit(Expr->getLHS()))
459 return true;
460
461 if (visit(Expr->getRHS()))
462 return true;
463
464 return false;
465 }
466
467 bool visitAddRecExpr(const SCEVAddRecExpr *Expr) {
468 if (visit(Expr->getStart()))
469 return true;
470
471 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
472 if (visit(Expr->getOperand(i)))
473 return true;
474
475 return false;
476 }
477
478 bool visitSMaxExpr(const SCEVSMaxExpr *Expr) {
479 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
480 if (visit(Expr->getOperand(i)))
481 return true;
482
483 return false;
484 }
485
486 bool visitUMaxExpr(const SCEVUMaxExpr *Expr) {
487 for (size_t i = 0; i < Expr->getNumOperands(); ++i)
488 if (visit(Expr->getOperand(i)))
489 return true;
490
491 return false;
492 }
493
494 bool visitUnknown(const SCEVUnknown *Expr) {
495 Instruction *Inst = dyn_cast<Instruction>(Expr->getValue());
496
497 // Return true when Inst is defined inside the region R.
498 if (Inst && R->contains(Inst))
499 return true;
500
501 return false;
502 }
503
504private:
505 const Region *R;
506};
507
Tobias Grosser120db6b2011-11-07 12:58:54 +0000508namespace polly {
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000509bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R) {
510 return SCEVInRegionDependences::hasDependences(Expr, R);
511}
Sebastian Pop97cb8132013-03-18 20:21:13 +0000512
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000513bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
514 const Value *BaseAddress) {
515 if (isa<SCEVCouldNotCompute>(Expr))
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000516 return false;
Tobias Grosser120db6b2011-11-07 12:58:54 +0000517
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000518 SCEVValidator Validator(R, SE, BaseAddress);
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000519 DEBUG(dbgs() << "\n"; dbgs() << "Expr: " << *Expr << "\n";
520 dbgs() << "Region: " << R->getNameStr() << "\n"; dbgs() << " -> ");
Tobias Grossereeb776a2012-09-08 14:00:37 +0000521
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000522 ValidatorResult Result = Validator.visit(Expr);
Tobias Grosser120db6b2011-11-07 12:58:54 +0000523
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000524 DEBUG(if (Result.isValid()) dbgs() << "VALID\n"; dbgs() << "\n";);
Tobias Grossereeb776a2012-09-08 14:00:37 +0000525
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000526 return Result.isValid();
527}
Tobias Grosser60b54f12011-11-08 15:41:28 +0000528
Tobias Grossere602a072013-05-07 07:30:56 +0000529std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
530 const SCEV *Expr,
531 ScalarEvolution &SE,
532 const Value *BaseAddress) {
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000533 if (isa<SCEVCouldNotCompute>(Expr))
534 return std::vector<const SCEV *>();
Tobias Grosser60b54f12011-11-08 15:41:28 +0000535
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000536 SCEVValidator Validator(R, SE, BaseAddress);
537 ValidatorResult Result = Validator.visit(Expr);
Tobias Grosser60b54f12011-11-08 15:41:28 +0000538
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000539 return Result.getParameters();
540}
Tobias Grosser120db6b2011-11-07 12:58:54 +0000541}