1 //===--------- ScopInfo.cpp  - Create Scops from LLVM IR ------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Create a polyhedral description for a static control flow region.
11 //
12 // The pass creates a polyhedral description of the Scops detected by the Scop
13 // detection derived from their LLVM-IR code.
14 //
15 // This represantation is shared among several tools in the polyhedral
16 // community, which are e.g. Cloog, Pluto, Loopo, Graphite.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #include "polly/CodeGen/BlockGenerators.h"
21 #include "polly/LinkAllPasses.h"
22 #include "polly/ScopInfo.h"
23 #include "polly/Options.h"
24 #include "polly/Support/GICHelper.h"
25 #include "polly/Support/SCEVValidator.h"
26 #include "polly/Support/ScopHelper.h"
27 #include "polly/TempScopInfo.h"
28 #include "llvm/ADT/SetVector.h"
29 #include "llvm/ADT/Statistic.h"
30 #include "llvm/ADT/StringExtras.h"
31 #include "llvm/Analysis/LoopInfo.h"
32 #include "llvm/Analysis/AliasAnalysis.h"
33 #include "llvm/Analysis/RegionIterator.h"
34 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
35 #include "llvm/Support/Debug.h"
36 
37 #include "isl/constraint.h"
38 #include "isl/set.h"
39 #include "isl/map.h"
40 #include "isl/union_map.h"
41 #include "isl/aff.h"
42 #include "isl/printer.h"
43 #include "isl/local_space.h"
44 #include "isl/options.h"
45 #include "isl/val.h"
46 
47 #include <sstream>
48 #include <string>
49 #include <vector>
50 
51 using namespace llvm;
52 using namespace polly;
53 
54 #define DEBUG_TYPE "polly-scops"
55 
56 STATISTIC(ScopFound, "Number of valid Scops");
57 STATISTIC(RichScopFound, "Number of Scops containing a loop");
58 
59 // Multiplicative reductions can be disabled separately as these kind of
60 // operations can overflow easily. Additive reductions and bit operations
61 // are in contrast pretty stable.
62 static cl::opt<bool> DisableMultiplicativeReductions(
63     "polly-disable-multiplicative-reductions",
64     cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore,
65     cl::init(false), cl::cat(PollyCategory));
66 
67 static cl::opt<unsigned> RunTimeChecksMaxParameters(
68     "polly-rtc-max-parameters",
69     cl::desc("The maximal number of parameters allowed in RTCs."), cl::Hidden,
70     cl::ZeroOrMore, cl::init(8), cl::cat(PollyCategory));
71 
72 /// Translate a 'const SCEV *' expression in an isl_pw_aff.
73 struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
74 public:
75   /// @brief Translate a 'const SCEV *' to an isl_pw_aff.
76   ///
77   /// @param Stmt The location at which the scalar evolution expression
78   ///             is evaluated.
79   /// @param Expr The expression that is translated.
80   static __isl_give isl_pw_aff *getPwAff(ScopStmt *Stmt, const SCEV *Expr);
81 
82 private:
83   isl_ctx *Ctx;
84   int NbLoopSpaces;
85   const Scop *S;
86 
87   SCEVAffinator(const ScopStmt *Stmt);
88   int getLoopDepth(const Loop *L);
89 
90   __isl_give isl_pw_aff *visit(const SCEV *Expr);
91   __isl_give isl_pw_aff *visitConstant(const SCEVConstant *Expr);
92   __isl_give isl_pw_aff *visitTruncateExpr(const SCEVTruncateExpr *Expr);
93   __isl_give isl_pw_aff *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr);
94   __isl_give isl_pw_aff *visitSignExtendExpr(const SCEVSignExtendExpr *Expr);
95   __isl_give isl_pw_aff *visitAddExpr(const SCEVAddExpr *Expr);
96   __isl_give isl_pw_aff *visitMulExpr(const SCEVMulExpr *Expr);
97   __isl_give isl_pw_aff *visitUDivExpr(const SCEVUDivExpr *Expr);
98   __isl_give isl_pw_aff *visitAddRecExpr(const SCEVAddRecExpr *Expr);
99   __isl_give isl_pw_aff *visitSMaxExpr(const SCEVSMaxExpr *Expr);
100   __isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr);
101   __isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr);
102 
103   friend struct SCEVVisitor<SCEVAffinator, isl_pw_aff *>;
104 };
105 
106 SCEVAffinator::SCEVAffinator(const ScopStmt *Stmt)
107     : Ctx(Stmt->getIslCtx()), NbLoopSpaces(Stmt->getNumIterators()),
108       S(Stmt->getParent()) {}
109 
110 __isl_give isl_pw_aff *SCEVAffinator::getPwAff(ScopStmt *Stmt,
111                                                const SCEV *Scev) {
112   Scop *S = Stmt->getParent();
113   const Region *Reg = &S->getRegion();
114 
115   S->addParams(getParamsInAffineExpr(Reg, Scev, *S->getSE()));
116 
117   SCEVAffinator Affinator(Stmt);
118   return Affinator.visit(Scev);
119 }
120 
121 __isl_give isl_pw_aff *SCEVAffinator::visit(const SCEV *Expr) {
122   // In case the scev is a valid parameter, we do not further analyze this
123   // expression, but create a new parameter in the isl_pw_aff. This allows us
124   // to treat subexpressions that we cannot translate into an piecewise affine
125   // expression, as constant parameters of the piecewise affine expression.
126   if (isl_id *Id = S->getIdForParam(Expr)) {
127     isl_space *Space = isl_space_set_alloc(Ctx, 1, NbLoopSpaces);
128     Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
129 
130     isl_set *Domain = isl_set_universe(isl_space_copy(Space));
131     isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space));
132     Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
133 
134     return isl_pw_aff_alloc(Domain, Affine);
135   }
136 
137   return SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Expr);
138 }
139 
140 __isl_give isl_pw_aff *SCEVAffinator::visitConstant(const SCEVConstant *Expr) {
141   ConstantInt *Value = Expr->getValue();
142   isl_val *v;
143 
144   // LLVM does not define if an integer value is interpreted as a signed or
145   // unsigned value. Hence, without further information, it is unknown how
146   // this value needs to be converted to GMP. At the moment, we only support
147   // signed operations. So we just interpret it as signed. Later, there are
148   // two options:
149   //
150   // 1. We always interpret any value as signed and convert the values on
151   //    demand.
152   // 2. We pass down the signedness of the calculation and use it to interpret
153   //    this constant correctly.
154   v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
155 
156   isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
157   isl_local_space *ls = isl_local_space_from_space(isl_space_copy(Space));
158   isl_aff *Affine = isl_aff_zero_on_domain(ls);
159   isl_set *Domain = isl_set_universe(Space);
160 
161   Affine = isl_aff_add_constant_val(Affine, v);
162 
163   return isl_pw_aff_alloc(Domain, Affine);
164 }
165 
166 __isl_give isl_pw_aff *
167 SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
168   llvm_unreachable("SCEVTruncateExpr not yet supported");
169 }
170 
171 __isl_give isl_pw_aff *
172 SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
173   llvm_unreachable("SCEVZeroExtendExpr not yet supported");
174 }
175 
176 __isl_give isl_pw_aff *
177 SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
178   // Assuming the value is signed, a sign extension is basically a noop.
179   // TODO: Reconsider this as soon as we support unsigned values.
180   return visit(Expr->getOperand());
181 }
182 
183 __isl_give isl_pw_aff *SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
184   isl_pw_aff *Sum = visit(Expr->getOperand(0));
185 
186   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
187     isl_pw_aff *NextSummand = visit(Expr->getOperand(i));
188     Sum = isl_pw_aff_add(Sum, NextSummand);
189   }
190 
191   // TODO: Check for NSW and NUW.
192 
193   return Sum;
194 }
195 
196 __isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) {
197   isl_pw_aff *Product = visit(Expr->getOperand(0));
198 
199   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
200     isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
201 
202     if (!isl_pw_aff_is_cst(Product) && !isl_pw_aff_is_cst(NextOperand)) {
203       isl_pw_aff_free(Product);
204       isl_pw_aff_free(NextOperand);
205       return nullptr;
206     }
207 
208     Product = isl_pw_aff_mul(Product, NextOperand);
209   }
210 
211   // TODO: Check for NSW and NUW.
212   return Product;
213 }
214 
215 __isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) {
216   llvm_unreachable("SCEVUDivExpr not yet supported");
217 }
218 
219 __isl_give isl_pw_aff *
220 SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
221   assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
222 
223   // Directly generate isl_pw_aff for Expr if 'start' is zero.
224   if (Expr->getStart()->isZero()) {
225     assert(S->getRegion().contains(Expr->getLoop()) &&
226            "Scop does not contain the loop referenced in this AddRec");
227 
228     isl_pw_aff *Start = visit(Expr->getStart());
229     isl_pw_aff *Step = visit(Expr->getOperand(1));
230     isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
231     isl_local_space *LocalSpace = isl_local_space_from_space(Space);
232 
233     int loopDimension = getLoopDepth(Expr->getLoop());
234 
235     isl_aff *LAff = isl_aff_set_coefficient_si(
236         isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
237     isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
238 
239     // TODO: Do we need to check for NSW and NUW?
240     return isl_pw_aff_add(Start, isl_pw_aff_mul(Step, LPwAff));
241   }
242 
243   // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
244   // if 'start' is not zero.
245   ScalarEvolution &SE = *S->getSE();
246   const SCEV *ZeroStartExpr = SE.getAddRecExpr(
247       SE.getConstant(Expr->getStart()->getType(), 0),
248       Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
249 
250   isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr);
251   isl_pw_aff *Start = visit(Expr->getStart());
252 
253   return isl_pw_aff_add(ZeroStartResult, Start);
254 }
255 
256 __isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) {
257   isl_pw_aff *Max = visit(Expr->getOperand(0));
258 
259   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
260     isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
261     Max = isl_pw_aff_max(Max, NextOperand);
262   }
263 
264   return Max;
265 }
266 
267 __isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) {
268   llvm_unreachable("SCEVUMaxExpr not yet supported");
269 }
270 
271 __isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) {
272   llvm_unreachable("Unknowns are always parameters");
273 }
274 
275 int SCEVAffinator::getLoopDepth(const Loop *L) {
276   Loop *outerLoop = S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L));
277   assert(outerLoop && "Scop does not contain this loop");
278   return L->getLoopDepth() - outerLoop->getLoopDepth();
279 }
280 
281 const std::string
282 MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
283   switch (RT) {
284   case MemoryAccess::RT_NONE:
285     llvm_unreachable("Requested a reduction operator string for a memory "
286                      "access which isn't a reduction");
287   case MemoryAccess::RT_ADD:
288     return "+";
289   case MemoryAccess::RT_MUL:
290     return "*";
291   case MemoryAccess::RT_BOR:
292     return "|";
293   case MemoryAccess::RT_BXOR:
294     return "^";
295   case MemoryAccess::RT_BAND:
296     return "&";
297   }
298   llvm_unreachable("Unknown reduction type");
299   return "";
300 }
301 
302 /// @brief Return the reduction type for a given binary operator
303 static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp,
304                                                     const Instruction *Load) {
305   if (!BinOp)
306     return MemoryAccess::RT_NONE;
307   switch (BinOp->getOpcode()) {
308   case Instruction::FAdd:
309     if (!BinOp->hasUnsafeAlgebra())
310       return MemoryAccess::RT_NONE;
311   // Fall through
312   case Instruction::Add:
313     return MemoryAccess::RT_ADD;
314   case Instruction::Or:
315     return MemoryAccess::RT_BOR;
316   case Instruction::Xor:
317     return MemoryAccess::RT_BXOR;
318   case Instruction::And:
319     return MemoryAccess::RT_BAND;
320   case Instruction::FMul:
321     if (!BinOp->hasUnsafeAlgebra())
322       return MemoryAccess::RT_NONE;
323   // Fall through
324   case Instruction::Mul:
325     if (DisableMultiplicativeReductions)
326       return MemoryAccess::RT_NONE;
327     return MemoryAccess::RT_MUL;
328   default:
329     return MemoryAccess::RT_NONE;
330   }
331 }
332 //===----------------------------------------------------------------------===//
333 
334 MemoryAccess::~MemoryAccess() {
335   isl_map_free(AccessRelation);
336   isl_map_free(newAccessRelation);
337 }
338 
339 static MemoryAccess::AccessType getMemoryAccessType(const IRAccess &Access) {
340   switch (Access.getType()) {
341   case IRAccess::READ:
342     return MemoryAccess::READ;
343   case IRAccess::MUST_WRITE:
344     return MemoryAccess::MUST_WRITE;
345   case IRAccess::MAY_WRITE:
346     return MemoryAccess::MAY_WRITE;
347   }
348   llvm_unreachable("Unknown IRAccess type!");
349 }
350 
351 isl_id *MemoryAccess::getArrayId() const {
352   return isl_map_get_tuple_id(AccessRelation, isl_dim_out);
353 }
354 
355 isl_map *MemoryAccess::getAccessRelation() const {
356   return isl_map_copy(AccessRelation);
357 }
358 
359 std::string MemoryAccess::getAccessRelationStr() const {
360   return stringFromIslObj(AccessRelation);
361 }
362 
363 __isl_give isl_space *MemoryAccess::getAccessRelationSpace() const {
364   return isl_map_get_space(AccessRelation);
365 }
366 
367 isl_map *MemoryAccess::getNewAccessRelation() const {
368   return isl_map_copy(newAccessRelation);
369 }
370 
371 isl_basic_map *MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
372   isl_space *Space = isl_space_set_alloc(Statement->getIslCtx(), 0, 1);
373   Space = isl_space_align_params(Space, Statement->getDomainSpace());
374 
375   return isl_basic_map_from_domain_and_range(
376       isl_basic_set_universe(Statement->getDomainSpace()),
377       isl_basic_set_universe(Space));
378 }
379 
380 // Formalize no out-of-bound access assumption
381 //
382 // When delinearizing array accesses we optimistically assume that the
383 // delinearized accesses do not access out of bound locations (the subscript
384 // expression of each array evaluates for each statement instance that is
385 // executed to a value that is larger than zero and strictly smaller than the
386 // size of the corresponding dimension). The only exception is the outermost
387 // dimension for which we do not need to assume any upper bound.  At this point
388 // we formalize this assumption to ensure that at code generation time the
389 // relevant run-time checks can be generated.
390 //
391 // To find the set of constraints necessary to avoid out of bound accesses, we
392 // first build the set of data locations that are not within array bounds. We
393 // then apply the reverse access relation to obtain the set of iterations that
394 // may contain invalid accesses and reduce this set of iterations to the ones
395 // that are actually executed by intersecting them with the domain of the
396 // statement. If we now project out all loop dimensions, we obtain a set of
397 // parameters that may cause statement instances to be executed that may
398 // possibly yield out of bound memory accesses. The complement of these
399 // constraints is the set of constraints that needs to be assumed to ensure such
400 // statement instances are never executed.
401 void MemoryAccess::assumeNoOutOfBound(const IRAccess &Access) {
402   isl_space *Space = isl_space_range(getAccessRelationSpace());
403   isl_set *Outside = isl_set_empty(isl_space_copy(Space));
404   for (int i = 1, Size = Access.Subscripts.size(); i < Size; ++i) {
405     isl_local_space *LS = isl_local_space_from_space(isl_space_copy(Space));
406     isl_pw_aff *Var =
407         isl_pw_aff_var_on_domain(isl_local_space_copy(LS), isl_dim_set, i);
408     isl_pw_aff *Zero = isl_pw_aff_zero_on_domain(LS);
409 
410     isl_set *DimOutside;
411 
412     DimOutside = isl_pw_aff_lt_set(isl_pw_aff_copy(Var), Zero);
413     isl_pw_aff *SizeE = SCEVAffinator::getPwAff(Statement, Access.Sizes[i - 1]);
414 
415     SizeE = isl_pw_aff_drop_dims(SizeE, isl_dim_in, 0,
416                                  Statement->getNumIterators());
417     SizeE = isl_pw_aff_add_dims(SizeE, isl_dim_in,
418                                 isl_space_dim(Space, isl_dim_set));
419     SizeE = isl_pw_aff_set_tuple_id(SizeE, isl_dim_in,
420                                     isl_space_get_tuple_id(Space, isl_dim_set));
421 
422     DimOutside = isl_set_union(DimOutside, isl_pw_aff_le_set(SizeE, Var));
423 
424     Outside = isl_set_union(Outside, DimOutside);
425   }
426 
427   Outside = isl_set_apply(Outside, isl_map_reverse(getAccessRelation()));
428   Outside = isl_set_intersect(Outside, Statement->getDomain());
429   Outside = isl_set_params(Outside);
430   Outside = isl_set_complement(Outside);
431   Statement->getParent()->addAssumption(Outside);
432   isl_space_free(Space);
433 }
434 
435 MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst,
436                            ScopStmt *Statement)
437     : Type(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst),
438       newAccessRelation(nullptr) {
439 
440   isl_ctx *Ctx = Statement->getIslCtx();
441   BaseAddr = Access.getBase();
442   BaseName = getIslCompatibleName("MemRef_", getBaseAddr(), "");
443   isl_id *BaseAddrId = isl_id_alloc(Ctx, getBaseName().c_str(), nullptr);
444 
445   if (!Access.isAffine()) {
446     // We overapproximate non-affine accesses with a possible access to the
447     // whole array. For read accesses it does not make a difference, if an
448     // access must or may happen. However, for write accesses it is important to
449     // differentiate between writes that must happen and writes that may happen.
450     AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
451     AccessRelation =
452         isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
453     return;
454   }
455 
456   isl_space *Space = isl_space_alloc(Ctx, 0, Statement->getNumIterators(), 0);
457   AccessRelation = isl_map_universe(Space);
458 
459   for (int i = 0, Size = Access.Subscripts.size(); i < Size; ++i) {
460     isl_pw_aff *Affine =
461         SCEVAffinator::getPwAff(Statement, Access.Subscripts[i]);
462 
463     if (Size == 1) {
464       // For the non delinearized arrays, divide the access function of the last
465       // subscript by the size of the elements in the array.
466       //
467       // A stride one array access in C expressed as A[i] is expressed in
468       // LLVM-IR as something like A[i * elementsize]. This hides the fact that
469       // two subsequent values of 'i' index two values that are stored next to
470       // each other in memory. By this division we make this characteristic
471       // obvious again.
472       isl_val *v = isl_val_int_from_si(Ctx, Access.getElemSizeInBytes());
473       Affine = isl_pw_aff_scale_down_val(Affine, v);
474     }
475 
476     isl_map *SubscriptMap = isl_map_from_pw_aff(Affine);
477 
478     AccessRelation = isl_map_flat_range_product(AccessRelation, SubscriptMap);
479   }
480 
481   Space = Statement->getDomainSpace();
482   AccessRelation = isl_map_set_tuple_id(
483       AccessRelation, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
484   AccessRelation =
485       isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
486 
487   assumeNoOutOfBound(Access);
488   isl_space_free(Space);
489 }
490 
491 void MemoryAccess::realignParams() {
492   isl_space *ParamSpace = Statement->getParent()->getParamSpace();
493   AccessRelation = isl_map_align_params(AccessRelation, ParamSpace);
494 }
495 
496 const std::string MemoryAccess::getReductionOperatorStr() const {
497   return MemoryAccess::getReductionOperatorStr(getReductionType());
498 }
499 
500 raw_ostream &polly::operator<<(raw_ostream &OS,
501                                MemoryAccess::ReductionType RT) {
502   if (RT == MemoryAccess::RT_NONE)
503     OS << "NONE";
504   else
505     OS << MemoryAccess::getReductionOperatorStr(RT);
506   return OS;
507 }
508 
509 void MemoryAccess::print(raw_ostream &OS) const {
510   switch (Type) {
511   case READ:
512     OS.indent(12) << "ReadAccess :=\t";
513     break;
514   case MUST_WRITE:
515     OS.indent(12) << "MustWriteAccess :=\t";
516     break;
517   case MAY_WRITE:
518     OS.indent(12) << "MayWriteAccess :=\t";
519     break;
520   }
521   OS << "[Reduction Type: " << getReductionType() << "]\n";
522   OS.indent(16) << getAccessRelationStr() << ";\n";
523 }
524 
525 void MemoryAccess::dump() const { print(errs()); }
526 
527 // Create a map in the size of the provided set domain, that maps from the
528 // one element of the provided set domain to another element of the provided
529 // set domain.
530 // The mapping is limited to all points that are equal in all but the last
531 // dimension and for which the last dimension of the input is strict smaller
532 // than the last dimension of the output.
533 //
534 //   getEqualAndLarger(set[i0, i1, ..., iX]):
535 //
536 //   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
537 //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
538 //
539 static isl_map *getEqualAndLarger(isl_space *setDomain) {
540   isl_space *Space = isl_space_map_from_set(setDomain);
541   isl_map *Map = isl_map_universe(isl_space_copy(Space));
542   isl_local_space *MapLocalSpace = isl_local_space_from_space(Space);
543   unsigned lastDimension = isl_map_dim(Map, isl_dim_in) - 1;
544 
545   // Set all but the last dimension to be equal for the input and output
546   //
547   //   input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
548   //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
549   for (unsigned i = 0; i < lastDimension; ++i)
550     Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
551 
552   // Set the last dimension of the input to be strict smaller than the
553   // last dimension of the output.
554   //
555   //   input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
556   //
557   isl_val *v;
558   isl_ctx *Ctx = isl_map_get_ctx(Map);
559   isl_constraint *c = isl_inequality_alloc(isl_local_space_copy(MapLocalSpace));
560   v = isl_val_int_from_si(Ctx, -1);
561   c = isl_constraint_set_coefficient_val(c, isl_dim_in, lastDimension, v);
562   v = isl_val_int_from_si(Ctx, 1);
563   c = isl_constraint_set_coefficient_val(c, isl_dim_out, lastDimension, v);
564   v = isl_val_int_from_si(Ctx, -1);
565   c = isl_constraint_set_constant_val(c, v);
566 
567   Map = isl_map_add_constraint(Map, c);
568 
569   isl_local_space_free(MapLocalSpace);
570   return Map;
571 }
572 
573 isl_set *MemoryAccess::getStride(__isl_take const isl_map *Schedule) const {
574   isl_map *S = const_cast<isl_map *>(Schedule);
575   isl_map *AccessRelation = getAccessRelation();
576   isl_space *Space = isl_space_range(isl_map_get_space(S));
577   isl_map *NextScatt = getEqualAndLarger(Space);
578 
579   S = isl_map_reverse(S);
580   NextScatt = isl_map_lexmin(NextScatt);
581 
582   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(S));
583   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(AccessRelation));
584   NextScatt = isl_map_apply_domain(NextScatt, S);
585   NextScatt = isl_map_apply_domain(NextScatt, AccessRelation);
586 
587   isl_set *Deltas = isl_map_deltas(NextScatt);
588   return Deltas;
589 }
590 
591 bool MemoryAccess::isStrideX(__isl_take const isl_map *Schedule,
592                              int StrideWidth) const {
593   isl_set *Stride, *StrideX;
594   bool IsStrideX;
595 
596   Stride = getStride(Schedule);
597   StrideX = isl_set_universe(isl_set_get_space(Stride));
598   StrideX = isl_set_fix_si(StrideX, isl_dim_set, 0, StrideWidth);
599   IsStrideX = isl_set_is_equal(Stride, StrideX);
600 
601   isl_set_free(StrideX);
602   isl_set_free(Stride);
603 
604   return IsStrideX;
605 }
606 
607 bool MemoryAccess::isStrideZero(const isl_map *Schedule) const {
608   return isStrideX(Schedule, 0);
609 }
610 
611 bool MemoryAccess::isScalar() const {
612   return isl_map_n_out(AccessRelation) == 0;
613 }
614 
615 bool MemoryAccess::isStrideOne(const isl_map *Schedule) const {
616   return isStrideX(Schedule, 1);
617 }
618 
619 void MemoryAccess::setNewAccessRelation(isl_map *newAccess) {
620   isl_map_free(newAccessRelation);
621   newAccessRelation = newAccess;
622 }
623 
624 //===----------------------------------------------------------------------===//
625 
626 isl_map *ScopStmt::getScattering() const { return isl_map_copy(Scattering); }
627 
628 void ScopStmt::restrictDomain(__isl_take isl_set *NewDomain) {
629   assert(isl_set_is_subset(NewDomain, Domain) &&
630          "New domain is not a subset of old domain!");
631   isl_set_free(Domain);
632   Domain = NewDomain;
633   Scattering = isl_map_intersect_domain(Scattering, isl_set_copy(Domain));
634 }
635 
636 void ScopStmt::setScattering(isl_map *NewScattering) {
637   assert(NewScattering && "New scattering is nullptr");
638   isl_map_free(Scattering);
639   Scattering = NewScattering;
640 }
641 
642 void ScopStmt::buildScattering(SmallVectorImpl<unsigned> &Scatter) {
643   unsigned NbIterators = getNumIterators();
644   unsigned NbScatteringDims = Parent.getMaxLoopDepth() * 2 + 1;
645 
646   isl_space *Space = isl_space_set_alloc(getIslCtx(), 0, NbScatteringDims);
647   Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering");
648 
649   Scattering = isl_map_from_domain_and_range(isl_set_universe(getDomainSpace()),
650                                              isl_set_universe(Space));
651 
652   // Loop dimensions.
653   for (unsigned i = 0; i < NbIterators; ++i)
654     Scattering =
655         isl_map_equate(Scattering, isl_dim_out, 2 * i + 1, isl_dim_in, i);
656 
657   // Constant dimensions
658   for (unsigned i = 0; i < NbIterators + 1; ++i)
659     Scattering = isl_map_fix_si(Scattering, isl_dim_out, 2 * i, Scatter[i]);
660 
661   // Fill scattering dimensions.
662   for (unsigned i = 2 * NbIterators + 1; i < NbScatteringDims; ++i)
663     Scattering = isl_map_fix_si(Scattering, isl_dim_out, i, 0);
664 
665   Scattering = isl_map_align_params(Scattering, Parent.getParamSpace());
666 }
667 
668 void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) {
669   for (auto &&Access : *tempScop.getAccessFunctions(BB)) {
670     MemAccs.push_back(new MemoryAccess(Access.first, Access.second, this));
671 
672     // We do not track locations for scalar memory accesses at the moment.
673     //
674     // We do not have a use for this information at the moment. If we need this
675     // at some point, the "instruction -> access" mapping needs to be enhanced
676     // as a single instruction could then possibly perform multiple accesses.
677     if (!Access.first.isScalar()) {
678       assert(!InstructionToAccess.count(Access.second) &&
679              "Unexpected 1-to-N mapping on instruction to access map!");
680       InstructionToAccess[Access.second] = MemAccs.back();
681     }
682   }
683 }
684 
685 void ScopStmt::realignParams() {
686   for (MemoryAccess *MA : *this)
687     MA->realignParams();
688 
689   Domain = isl_set_align_params(Domain, Parent.getParamSpace());
690   Scattering = isl_map_align_params(Scattering, Parent.getParamSpace());
691 }
692 
693 __isl_give isl_set *ScopStmt::buildConditionSet(const Comparison &Comp) {
694   isl_pw_aff *L = SCEVAffinator::getPwAff(this, Comp.getLHS());
695   isl_pw_aff *R = SCEVAffinator::getPwAff(this, Comp.getRHS());
696 
697   switch (Comp.getPred()) {
698   case ICmpInst::ICMP_EQ:
699     return isl_pw_aff_eq_set(L, R);
700   case ICmpInst::ICMP_NE:
701     return isl_pw_aff_ne_set(L, R);
702   case ICmpInst::ICMP_SLT:
703     return isl_pw_aff_lt_set(L, R);
704   case ICmpInst::ICMP_SLE:
705     return isl_pw_aff_le_set(L, R);
706   case ICmpInst::ICMP_SGT:
707     return isl_pw_aff_gt_set(L, R);
708   case ICmpInst::ICMP_SGE:
709     return isl_pw_aff_ge_set(L, R);
710   case ICmpInst::ICMP_ULT:
711   case ICmpInst::ICMP_UGT:
712   case ICmpInst::ICMP_ULE:
713   case ICmpInst::ICMP_UGE:
714     llvm_unreachable("Unsigned comparisons not yet supported");
715   default:
716     llvm_unreachable("Non integer predicate not supported");
717   }
718 }
719 
720 __isl_give isl_set *ScopStmt::addLoopBoundsToDomain(__isl_take isl_set *Domain,
721                                                     TempScop &tempScop) {
722   isl_space *Space;
723   isl_local_space *LocalSpace;
724 
725   Space = isl_set_get_space(Domain);
726   LocalSpace = isl_local_space_from_space(Space);
727 
728   for (int i = 0, e = getNumIterators(); i != e; ++i) {
729     isl_aff *Zero = isl_aff_zero_on_domain(isl_local_space_copy(LocalSpace));
730     isl_pw_aff *IV =
731         isl_pw_aff_from_aff(isl_aff_set_coefficient_si(Zero, isl_dim_in, i, 1));
732 
733     // 0 <= IV.
734     isl_set *LowerBound = isl_pw_aff_nonneg_set(isl_pw_aff_copy(IV));
735     Domain = isl_set_intersect(Domain, LowerBound);
736 
737     // IV <= LatchExecutions.
738     const Loop *L = getLoopForDimension(i);
739     const SCEV *LatchExecutions = tempScop.getLoopBound(L);
740     isl_pw_aff *UpperBound = SCEVAffinator::getPwAff(this, LatchExecutions);
741     isl_set *UpperBoundSet = isl_pw_aff_le_set(IV, UpperBound);
742     Domain = isl_set_intersect(Domain, UpperBoundSet);
743   }
744 
745   isl_local_space_free(LocalSpace);
746   return Domain;
747 }
748 
749 __isl_give isl_set *ScopStmt::addConditionsToDomain(__isl_take isl_set *Domain,
750                                                     TempScop &tempScop,
751                                                     const Region &CurRegion) {
752   const Region *TopRegion = tempScop.getMaxRegion().getParent(),
753                *CurrentRegion = &CurRegion;
754   const BasicBlock *BranchingBB = BB;
755 
756   do {
757     if (BranchingBB != CurrentRegion->getEntry()) {
758       if (const BBCond *Condition = tempScop.getBBCond(BranchingBB))
759         for (const auto &C : *Condition) {
760           isl_set *ConditionSet = buildConditionSet(C);
761           Domain = isl_set_intersect(Domain, ConditionSet);
762         }
763     }
764     BranchingBB = CurrentRegion->getEntry();
765     CurrentRegion = CurrentRegion->getParent();
766   } while (TopRegion != CurrentRegion);
767 
768   return Domain;
769 }
770 
771 __isl_give isl_set *ScopStmt::buildDomain(TempScop &tempScop,
772                                           const Region &CurRegion) {
773   isl_space *Space;
774   isl_set *Domain;
775   isl_id *Id;
776 
777   Space = isl_space_set_alloc(getIslCtx(), 0, getNumIterators());
778 
779   Id = isl_id_alloc(getIslCtx(), getBaseName(), this);
780 
781   Domain = isl_set_universe(Space);
782   Domain = addLoopBoundsToDomain(Domain, tempScop);
783   Domain = addConditionsToDomain(Domain, tempScop, CurRegion);
784   Domain = isl_set_set_tuple_id(Domain, Id);
785 
786   return Domain;
787 }
788 
789 ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
790                    BasicBlock &bb, SmallVectorImpl<Loop *> &Nest,
791                    SmallVectorImpl<unsigned> &Scatter)
792     : Parent(parent), BB(&bb), IVS(Nest.size()), NestLoops(Nest.size()) {
793   // Setup the induction variables.
794   for (unsigned i = 0, e = Nest.size(); i < e; ++i) {
795     if (!SCEVCodegen) {
796       PHINode *PN = Nest[i]->getCanonicalInductionVariable();
797       assert(PN && "Non canonical IV in Scop!");
798       IVS[i] = PN;
799     }
800     NestLoops[i] = Nest[i];
801   }
802 
803   BaseName = getIslCompatibleName("Stmt_", &bb, "");
804 
805   Domain = buildDomain(tempScop, CurRegion);
806   buildScattering(Scatter);
807   buildAccesses(tempScop, CurRegion);
808   checkForReductions();
809 }
810 
811 /// @brief Collect loads which might form a reduction chain with @p StoreMA
812 ///
813 /// Check if the stored value for @p StoreMA is a binary operator with one or
814 /// two loads as operands. If the binary operand is commutative & associative,
815 /// used only once (by @p StoreMA) and its load operands are also used only
816 /// once, we have found a possible reduction chain. It starts at an operand
817 /// load and includes the binary operator and @p StoreMA.
818 ///
819 /// Note: We allow only one use to ensure the load and binary operator cannot
820 ///       escape this block or into any other store except @p StoreMA.
821 void ScopStmt::collectCandiateReductionLoads(
822     MemoryAccess *StoreMA, SmallVectorImpl<MemoryAccess *> &Loads) {
823   auto *Store = dyn_cast<StoreInst>(StoreMA->getAccessInstruction());
824   if (!Store)
825     return;
826 
827   // Skip if there is not one binary operator between the load and the store
828   auto *BinOp = dyn_cast<BinaryOperator>(Store->getValueOperand());
829   if (!BinOp)
830     return;
831 
832   // Skip if the binary operators has multiple uses
833   if (BinOp->getNumUses() != 1)
834     return;
835 
836   // Skip if the opcode of the binary operator is not commutative/associative
837   if (!BinOp->isCommutative() || !BinOp->isAssociative())
838     return;
839 
840   // Skip if the binary operator is outside the current SCoP
841   if (BinOp->getParent() != Store->getParent())
842     return;
843 
844   // Skip if it is a multiplicative reduction and we disabled them
845   if (DisableMultiplicativeReductions &&
846       (BinOp->getOpcode() == Instruction::Mul ||
847        BinOp->getOpcode() == Instruction::FMul))
848     return;
849 
850   // Check the binary operator operands for a candidate load
851   auto *PossibleLoad0 = dyn_cast<LoadInst>(BinOp->getOperand(0));
852   auto *PossibleLoad1 = dyn_cast<LoadInst>(BinOp->getOperand(1));
853   if (!PossibleLoad0 && !PossibleLoad1)
854     return;
855 
856   // A load is only a candidate if it cannot escape (thus has only this use)
857   if (PossibleLoad0 && PossibleLoad0->getNumUses() == 1)
858     if (PossibleLoad0->getParent() == Store->getParent())
859       Loads.push_back(lookupAccessFor(PossibleLoad0));
860   if (PossibleLoad1 && PossibleLoad1->getNumUses() == 1)
861     if (PossibleLoad1->getParent() == Store->getParent())
862       Loads.push_back(lookupAccessFor(PossibleLoad1));
863 }
864 
865 /// @brief Check for reductions in this ScopStmt
866 ///
867 /// Iterate over all store memory accesses and check for valid binary reduction
868 /// like chains. For all candidates we check if they have the same base address
869 /// and there are no other accesses which overlap with them. The base address
870 /// check rules out impossible reductions candidates early. The overlap check,
871 /// together with the "only one user" check in collectCandiateReductionLoads,
872 /// guarantees that none of the intermediate results will escape during
873 /// execution of the loop nest. We basically check here that no other memory
874 /// access can access the same memory as the potential reduction.
875 void ScopStmt::checkForReductions() {
876   SmallVector<MemoryAccess *, 2> Loads;
877   SmallVector<std::pair<MemoryAccess *, MemoryAccess *>, 4> Candidates;
878 
879   // First collect candidate load-store reduction chains by iterating over all
880   // stores and collecting possible reduction loads.
881   for (MemoryAccess *StoreMA : MemAccs) {
882     if (StoreMA->isRead())
883       continue;
884 
885     Loads.clear();
886     collectCandiateReductionLoads(StoreMA, Loads);
887     for (MemoryAccess *LoadMA : Loads)
888       Candidates.push_back(std::make_pair(LoadMA, StoreMA));
889   }
890 
891   // Then check each possible candidate pair.
892   for (const auto &CandidatePair : Candidates) {
893     bool Valid = true;
894     isl_map *LoadAccs = CandidatePair.first->getAccessRelation();
895     isl_map *StoreAccs = CandidatePair.second->getAccessRelation();
896 
897     // Skip those with obviously unequal base addresses.
898     if (!isl_map_has_equal_space(LoadAccs, StoreAccs)) {
899       isl_map_free(LoadAccs);
900       isl_map_free(StoreAccs);
901       continue;
902     }
903 
904     // And check if the remaining for overlap with other memory accesses.
905     isl_map *AllAccsRel = isl_map_union(LoadAccs, StoreAccs);
906     AllAccsRel = isl_map_intersect_domain(AllAccsRel, getDomain());
907     isl_set *AllAccs = isl_map_range(AllAccsRel);
908 
909     for (MemoryAccess *MA : MemAccs) {
910       if (MA == CandidatePair.first || MA == CandidatePair.second)
911         continue;
912 
913       isl_map *AccRel =
914           isl_map_intersect_domain(MA->getAccessRelation(), getDomain());
915       isl_set *Accs = isl_map_range(AccRel);
916 
917       if (isl_set_has_equal_space(AllAccs, Accs) || isl_set_free(Accs)) {
918         isl_set *OverlapAccs = isl_set_intersect(Accs, isl_set_copy(AllAccs));
919         Valid = Valid && isl_set_is_empty(OverlapAccs);
920         isl_set_free(OverlapAccs);
921       }
922     }
923 
924     isl_set_free(AllAccs);
925     if (!Valid)
926       continue;
927 
928     const LoadInst *Load =
929         dyn_cast<const LoadInst>(CandidatePair.first->getAccessInstruction());
930     MemoryAccess::ReductionType RT =
931         getReductionType(dyn_cast<BinaryOperator>(Load->user_back()), Load);
932 
933     // If no overlapping access was found we mark the load and store as
934     // reduction like.
935     CandidatePair.first->markAsReductionLike(RT);
936     CandidatePair.second->markAsReductionLike(RT);
937   }
938 }
939 
940 std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
941 
942 std::string ScopStmt::getScatteringStr() const {
943   return stringFromIslObj(Scattering);
944 }
945 
946 unsigned ScopStmt::getNumParams() const { return Parent.getNumParams(); }
947 
948 unsigned ScopStmt::getNumIterators() const {
949   // The final read has one dimension with one element.
950   if (!BB)
951     return 1;
952 
953   return NestLoops.size();
954 }
955 
956 unsigned ScopStmt::getNumScattering() const {
957   return isl_map_dim(Scattering, isl_dim_out);
958 }
959 
960 const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
961 
962 const PHINode *
963 ScopStmt::getInductionVariableForDimension(unsigned Dimension) const {
964   return IVS[Dimension];
965 }
966 
967 const Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
968   return NestLoops[Dimension];
969 }
970 
971 isl_ctx *ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
972 
973 isl_set *ScopStmt::getDomain() const { return isl_set_copy(Domain); }
974 
975 isl_space *ScopStmt::getDomainSpace() const {
976   return isl_set_get_space(Domain);
977 }
978 
979 isl_id *ScopStmt::getDomainId() const { return isl_set_get_tuple_id(Domain); }
980 
981 ScopStmt::~ScopStmt() {
982   while (!MemAccs.empty()) {
983     delete MemAccs.back();
984     MemAccs.pop_back();
985   }
986 
987   isl_set_free(Domain);
988   isl_map_free(Scattering);
989 }
990 
991 void ScopStmt::print(raw_ostream &OS) const {
992   OS << "\t" << getBaseName() << "\n";
993   OS.indent(12) << "Domain :=\n";
994 
995   if (Domain) {
996     OS.indent(16) << getDomainStr() << ";\n";
997   } else
998     OS.indent(16) << "n/a\n";
999 
1000   OS.indent(12) << "Scattering :=\n";
1001 
1002   if (Domain) {
1003     OS.indent(16) << getScatteringStr() << ";\n";
1004   } else
1005     OS.indent(16) << "n/a\n";
1006 
1007   for (MemoryAccess *Access : MemAccs)
1008     Access->print(OS);
1009 }
1010 
1011 void ScopStmt::dump() const { print(dbgs()); }
1012 
1013 //===----------------------------------------------------------------------===//
1014 /// Scop class implement
1015 
1016 void Scop::setContext(__isl_take isl_set *NewContext) {
1017   NewContext = isl_set_align_params(NewContext, isl_set_get_space(Context));
1018   isl_set_free(Context);
1019   Context = NewContext;
1020 }
1021 
1022 void Scop::addParams(std::vector<const SCEV *> NewParameters) {
1023   for (const SCEV *Parameter : NewParameters) {
1024     if (ParameterIds.find(Parameter) != ParameterIds.end())
1025       continue;
1026 
1027     int dimension = Parameters.size();
1028 
1029     Parameters.push_back(Parameter);
1030     ParameterIds[Parameter] = dimension;
1031   }
1032 }
1033 
1034 __isl_give isl_id *Scop::getIdForParam(const SCEV *Parameter) const {
1035   ParamIdType::const_iterator IdIter = ParameterIds.find(Parameter);
1036 
1037   if (IdIter == ParameterIds.end())
1038     return nullptr;
1039 
1040   std::string ParameterName;
1041 
1042   if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
1043     Value *Val = ValueParameter->getValue();
1044     ParameterName = Val->getName();
1045   }
1046 
1047   if (ParameterName == "" || ParameterName.substr(0, 2) == "p_")
1048     ParameterName = "p_" + utostr_32(IdIter->second);
1049 
1050   return isl_id_alloc(getIslCtx(), ParameterName.c_str(),
1051                       const_cast<void *>((const void *)Parameter));
1052 }
1053 
1054 void Scop::buildContext() {
1055   isl_space *Space = isl_space_params_alloc(IslCtx, 0);
1056   Context = isl_set_universe(isl_space_copy(Space));
1057   AssumedContext = isl_set_universe(Space);
1058 }
1059 
1060 void Scop::addParameterBounds() {
1061   for (unsigned i = 0; i < isl_set_dim(Context, isl_dim_param); ++i) {
1062     isl_val *V;
1063     isl_id *Id;
1064     const SCEV *Scev;
1065     const IntegerType *T;
1066 
1067     Id = isl_set_get_dim_id(Context, isl_dim_param, i);
1068     Scev = (const SCEV *)isl_id_get_user(Id);
1069     T = dyn_cast<IntegerType>(Scev->getType());
1070     isl_id_free(Id);
1071 
1072     assert(T && "Not an integer type");
1073     int Width = T->getBitWidth();
1074 
1075     V = isl_val_int_from_si(IslCtx, Width - 1);
1076     V = isl_val_2exp(V);
1077     V = isl_val_neg(V);
1078     Context = isl_set_lower_bound_val(Context, isl_dim_param, i, V);
1079 
1080     V = isl_val_int_from_si(IslCtx, Width - 1);
1081     V = isl_val_2exp(V);
1082     V = isl_val_sub_ui(V, 1);
1083     Context = isl_set_upper_bound_val(Context, isl_dim_param, i, V);
1084   }
1085 }
1086 
1087 void Scop::realignParams() {
1088   // Add all parameters into a common model.
1089   isl_space *Space = isl_space_params_alloc(IslCtx, ParameterIds.size());
1090 
1091   for (const auto &ParamID : ParameterIds) {
1092     const SCEV *Parameter = ParamID.first;
1093     isl_id *id = getIdForParam(Parameter);
1094     Space = isl_space_set_dim_id(Space, isl_dim_param, ParamID.second, id);
1095   }
1096 
1097   // Align the parameters of all data structures to the model.
1098   Context = isl_set_align_params(Context, Space);
1099 
1100   for (ScopStmt *Stmt : *this)
1101     Stmt->realignParams();
1102 }
1103 
1104 void Scop::simplifyAssumedContext() {
1105   // The parameter constraints of the iteration domains give us a set of
1106   // constraints that need to hold for all cases where at least a single
1107   // statement iteration is executed in the whole scop. We now simplify the
1108   // assumed context under the assumption that such constraints hold and at
1109   // least a single statement iteration is executed. For cases where no
1110   // statement instances are executed, the assumptions we have taken about
1111   // the executed code do not matter and can be changed.
1112   //
1113   // WARNING: This only holds if the assumptions we have taken do not reduce
1114   //          the set of statement instances that are executed. Otherwise we
1115   //          may run into a case where the iteration domains suggest that
1116   //          for a certain set of parameter constraints no code is executed,
1117   //          but in the original program some computation would have been
1118   //          performed. In such a case, modifying the run-time conditions and
1119   //          possibly influencing the run-time check may cause certain scops
1120   //          to not be executed.
1121   //
1122   // Example:
1123   //
1124   //   When delinearizing the following code:
1125   //
1126   //     for (long i = 0; i < 100; i++)
1127   //       for (long j = 0; j < m; j++)
1128   //         A[i+p][j] = 1.0;
1129   //
1130   //   we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
1131   //   otherwise we would access out of bound data. Now, knowing that code is
1132   //   only executed for the case m >= 0, it is sufficient to assume p >= 0.
1133   AssumedContext =
1134       isl_set_gist_params(AssumedContext, isl_union_set_params(getDomains()));
1135 }
1136 
1137 /// @brief Add the minimal/maximal access in @p Set to @p User.
1138 static int buildMinMaxAccess(__isl_take isl_set *Set, void *User) {
1139   Scop::MinMaxVectorTy *MinMaxAccesses = (Scop::MinMaxVectorTy *)User;
1140   isl_pw_multi_aff *MinPMA, *MaxPMA;
1141   isl_pw_aff *LastDimAff;
1142   isl_aff *OneAff;
1143   unsigned Pos;
1144 
1145   // Restrict the number of parameters involved in the access as the lexmin/
1146   // lexmax computation will take too long if this number is high.
1147   //
1148   // Experiments with a simple test case using an i7 4800MQ:
1149   //
1150   //  #Parameters involved | Time (in sec)
1151   //            6          |     0.01
1152   //            7          |     0.04
1153   //            8          |     0.12
1154   //            9          |     0.40
1155   //           10          |     1.54
1156   //           11          |     6.78
1157   //           12          |    30.38
1158   //
1159   if (isl_set_n_param(Set) > RunTimeChecksMaxParameters) {
1160     unsigned InvolvedParams = 0;
1161     for (unsigned u = 0, e = isl_set_n_param(Set); u < e; u++)
1162       if (isl_set_involves_dims(Set, isl_dim_param, u, 1))
1163         InvolvedParams++;
1164 
1165     if (InvolvedParams > RunTimeChecksMaxParameters) {
1166       isl_set_free(Set);
1167       return -1;
1168     }
1169   }
1170 
1171   MinPMA = isl_set_lexmin_pw_multi_aff(isl_set_copy(Set));
1172   MaxPMA = isl_set_lexmax_pw_multi_aff(isl_set_copy(Set));
1173 
1174   // Adjust the last dimension of the maximal access by one as we want to
1175   // enclose the accessed memory region by MinPMA and MaxPMA. The pointer
1176   // we test during code generation might now point after the end of the
1177   // allocated array but we will never dereference it anyway.
1178   assert(isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) &&
1179          "Assumed at least one output dimension");
1180   Pos = isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) - 1;
1181   LastDimAff = isl_pw_multi_aff_get_pw_aff(MaxPMA, Pos);
1182   OneAff = isl_aff_zero_on_domain(
1183       isl_local_space_from_space(isl_pw_aff_get_domain_space(LastDimAff)));
1184   OneAff = isl_aff_add_constant_si(OneAff, 1);
1185   LastDimAff = isl_pw_aff_add(LastDimAff, isl_pw_aff_from_aff(OneAff));
1186   MaxPMA = isl_pw_multi_aff_set_pw_aff(MaxPMA, Pos, LastDimAff);
1187 
1188   MinMaxAccesses->push_back(std::make_pair(MinPMA, MaxPMA));
1189 
1190   isl_set_free(Set);
1191   return 0;
1192 }
1193 
1194 static __isl_give isl_set *getAccessDomain(MemoryAccess *MA) {
1195   isl_set *Domain = MA->getStatement()->getDomain();
1196   Domain = isl_set_project_out(Domain, isl_dim_set, 0, isl_set_n_dim(Domain));
1197   return isl_set_reset_tuple_id(Domain);
1198 }
1199 
1200 bool Scop::buildAliasGroups(AliasAnalysis &AA) {
1201   // To create sound alias checks we perform the following steps:
1202   //   o) Use the alias analysis and an alias set tracker to build alias sets
1203   //      for all memory accesses inside the SCoP.
1204   //   o) For each alias set we then map the aliasing pointers back to the
1205   //      memory accesses we know, thus obtain groups of memory accesses which
1206   //      might alias.
1207   //   o) We divide each group based on the domains of the minimal/maximal
1208   //      accesses. That means two minimal/maximal accesses are only in a group
1209   //      if their access domains intersect, otherwise they are in different
1210   //      ones.
1211   //   o) We split groups such that they contain at most one read only base
1212   //      address.
1213   //   o) For each group with more than one base pointer we then compute minimal
1214   //      and maximal accesses to each array in this group.
1215   using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
1216 
1217   AliasSetTracker AST(AA);
1218 
1219   DenseMap<Value *, MemoryAccess *> PtrToAcc;
1220   DenseSet<Value *> HasWriteAccess;
1221   for (ScopStmt *Stmt : *this) {
1222     for (MemoryAccess *MA : *Stmt) {
1223       if (MA->isScalar())
1224         continue;
1225       if (!MA->isRead())
1226         HasWriteAccess.insert(MA->getBaseAddr());
1227       Instruction *Acc = MA->getAccessInstruction();
1228       PtrToAcc[getPointerOperand(*Acc)] = MA;
1229       AST.add(Acc);
1230     }
1231   }
1232 
1233   SmallVector<AliasGroupTy, 4> AliasGroups;
1234   for (AliasSet &AS : AST) {
1235     if (AS.isMustAlias())
1236       continue;
1237     AliasGroupTy AG;
1238     for (auto PR : AS)
1239       AG.push_back(PtrToAcc[PR.getValue()]);
1240     assert(AG.size() > 1 &&
1241            "Alias groups should contain at least two accesses");
1242     AliasGroups.push_back(std::move(AG));
1243   }
1244 
1245   // Split the alias groups based on their domain.
1246   for (unsigned u = 0; u < AliasGroups.size(); u++) {
1247     AliasGroupTy NewAG;
1248     AliasGroupTy &AG = AliasGroups[u];
1249     AliasGroupTy::iterator AGI = AG.begin();
1250     isl_set *AGDomain = getAccessDomain(*AGI);
1251     while (AGI != AG.end()) {
1252       MemoryAccess *MA = *AGI;
1253       isl_set *MADomain = getAccessDomain(MA);
1254       if (isl_set_is_disjoint(AGDomain, MADomain)) {
1255         NewAG.push_back(MA);
1256         AGI = AG.erase(AGI);
1257         isl_set_free(MADomain);
1258       } else {
1259         AGDomain = isl_set_union(AGDomain, MADomain);
1260         AGI++;
1261       }
1262     }
1263     if (NewAG.size() > 1)
1264       AliasGroups.push_back(std::move(NewAG));
1265     isl_set_free(AGDomain);
1266   }
1267 
1268   DenseMap<const Value *, SmallPtrSet<MemoryAccess *, 8>> ReadOnlyPairs;
1269   SmallPtrSet<const Value *, 4> NonReadOnlyBaseValues;
1270   for (AliasGroupTy &AG : AliasGroups) {
1271     NonReadOnlyBaseValues.clear();
1272     ReadOnlyPairs.clear();
1273 
1274     if (AG.size() < 2) {
1275       AG.clear();
1276       continue;
1277     }
1278 
1279     for (auto II = AG.begin(); II != AG.end();) {
1280       Value *BaseAddr = (*II)->getBaseAddr();
1281       if (HasWriteAccess.count(BaseAddr)) {
1282         NonReadOnlyBaseValues.insert(BaseAddr);
1283         II++;
1284       } else {
1285         ReadOnlyPairs[BaseAddr].insert(*II);
1286         II = AG.erase(II);
1287       }
1288     }
1289 
1290     // If we don't have read only pointers check if there are at least two
1291     // non read only pointers, otherwise clear the alias group.
1292     if (ReadOnlyPairs.empty()) {
1293       if (NonReadOnlyBaseValues.size() <= 1)
1294         AG.clear();
1295       continue;
1296     }
1297 
1298     // If we don't have non read only pointers clear the alias group.
1299     if (NonReadOnlyBaseValues.empty()) {
1300       AG.clear();
1301       continue;
1302     }
1303 
1304     // If we have both read only and non read only base pointers we combine
1305     // the non read only ones with exactly one read only one at a time into a
1306     // new alias group and clear the old alias group in the end.
1307     for (const auto &ReadOnlyPair : ReadOnlyPairs) {
1308       AliasGroupTy AGNonReadOnly = AG;
1309       for (MemoryAccess *MA : ReadOnlyPair.second)
1310         AGNonReadOnly.push_back(MA);
1311       AliasGroups.push_back(std::move(AGNonReadOnly));
1312     }
1313     AG.clear();
1314   }
1315 
1316   bool Valid = true;
1317   for (AliasGroupTy &AG : AliasGroups) {
1318     if (AG.empty())
1319       continue;
1320 
1321     MinMaxVectorTy *MinMaxAccesses = new MinMaxVectorTy();
1322     MinMaxAccesses->reserve(AG.size());
1323 
1324     isl_union_map *Accesses = isl_union_map_empty(getParamSpace());
1325     for (MemoryAccess *MA : AG)
1326       Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation());
1327     Accesses = isl_union_map_intersect_domain(Accesses, getDomains());
1328 
1329     isl_union_set *Locations = isl_union_map_range(Accesses);
1330     Locations = isl_union_set_intersect_params(Locations, getAssumedContext());
1331     Locations = isl_union_set_coalesce(Locations);
1332     Locations = isl_union_set_detect_equalities(Locations);
1333     Valid = (0 == isl_union_set_foreach_set(Locations, buildMinMaxAccess,
1334                                             MinMaxAccesses));
1335     isl_union_set_free(Locations);
1336     MinMaxAliasGroups.push_back(MinMaxAccesses);
1337 
1338     if (!Valid)
1339       break;
1340   }
1341 
1342   return Valid;
1343 }
1344 
1345 Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution,
1346            isl_ctx *Context)
1347     : SE(&ScalarEvolution), R(tempScop.getMaxRegion()),
1348       MaxLoopDepth(tempScop.getMaxLoopDepth()) {
1349   IslCtx = Context;
1350   buildContext();
1351 
1352   SmallVector<Loop *, 8> NestLoops;
1353   SmallVector<unsigned, 8> Scatter;
1354 
1355   Scatter.assign(MaxLoopDepth + 1, 0);
1356 
1357   // Build the iteration domain, access functions and scattering functions
1358   // traversing the region tree.
1359   buildScop(tempScop, getRegion(), NestLoops, Scatter, LI);
1360 
1361   realignParams();
1362   addParameterBounds();
1363   simplifyAssumedContext();
1364 
1365   assert(NestLoops.empty() && "NestLoops not empty at top level!");
1366 }
1367 
1368 Scop::~Scop() {
1369   isl_set_free(Context);
1370   isl_set_free(AssumedContext);
1371 
1372   // Free the statements;
1373   for (ScopStmt *Stmt : *this)
1374     delete Stmt;
1375 
1376   // Free the alias groups
1377   for (MinMaxVectorTy *MinMaxAccesses : MinMaxAliasGroups) {
1378     for (MinMaxAccessTy &MMA : *MinMaxAccesses) {
1379       isl_pw_multi_aff_free(MMA.first);
1380       isl_pw_multi_aff_free(MMA.second);
1381     }
1382     delete MinMaxAccesses;
1383   }
1384 }
1385 
1386 std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
1387 std::string Scop::getAssumedContextStr() const {
1388   return stringFromIslObj(AssumedContext);
1389 }
1390 
1391 std::string Scop::getNameStr() const {
1392   std::string ExitName, EntryName;
1393   raw_string_ostream ExitStr(ExitName);
1394   raw_string_ostream EntryStr(EntryName);
1395 
1396   R.getEntry()->printAsOperand(EntryStr, false);
1397   EntryStr.str();
1398 
1399   if (R.getExit()) {
1400     R.getExit()->printAsOperand(ExitStr, false);
1401     ExitStr.str();
1402   } else
1403     ExitName = "FunctionExit";
1404 
1405   return EntryName + "---" + ExitName;
1406 }
1407 
1408 __isl_give isl_set *Scop::getContext() const { return isl_set_copy(Context); }
1409 __isl_give isl_space *Scop::getParamSpace() const {
1410   return isl_set_get_space(this->Context);
1411 }
1412 
1413 __isl_give isl_set *Scop::getAssumedContext() const {
1414   return isl_set_copy(AssumedContext);
1415 }
1416 
1417 void Scop::addAssumption(__isl_take isl_set *Set) {
1418   AssumedContext = isl_set_intersect(AssumedContext, Set);
1419 }
1420 
1421 void Scop::printContext(raw_ostream &OS) const {
1422   OS << "Context:\n";
1423 
1424   if (!Context) {
1425     OS.indent(4) << "n/a\n\n";
1426     return;
1427   }
1428 
1429   OS.indent(4) << getContextStr() << "\n";
1430 
1431   OS.indent(4) << "Assumed Context:\n";
1432   if (!AssumedContext) {
1433     OS.indent(4) << "n/a\n\n";
1434     return;
1435   }
1436 
1437   OS.indent(4) << getAssumedContextStr() << "\n";
1438 
1439   for (const SCEV *Parameter : Parameters) {
1440     int Dim = ParameterIds.find(Parameter)->second;
1441     OS.indent(4) << "p" << Dim << ": " << *Parameter << "\n";
1442   }
1443 }
1444 
1445 void Scop::printAliasAssumptions(raw_ostream &OS) const {
1446   OS.indent(4) << "Alias Groups (" << MinMaxAliasGroups.size() << "):\n";
1447   if (MinMaxAliasGroups.empty()) {
1448     OS.indent(8) << "n/a\n";
1449     return;
1450   }
1451   for (MinMaxVectorTy *MinMaxAccesses : MinMaxAliasGroups) {
1452     OS.indent(8) << "[[";
1453     for (MinMaxAccessTy &MinMacAccess : *MinMaxAccesses)
1454       OS << " <" << MinMacAccess.first << ", " << MinMacAccess.second << ">";
1455     OS << " ]]\n";
1456   }
1457 }
1458 
1459 void Scop::printStatements(raw_ostream &OS) const {
1460   OS << "Statements {\n";
1461 
1462   for (ScopStmt *Stmt : *this)
1463     OS.indent(4) << *Stmt;
1464 
1465   OS.indent(4) << "}\n";
1466 }
1467 
1468 void Scop::print(raw_ostream &OS) const {
1469   OS.indent(4) << "Function: " << getRegion().getEntry()->getParent()->getName()
1470                << "\n";
1471   OS.indent(4) << "Region: " << getNameStr() << "\n";
1472   printContext(OS.indent(4));
1473   printAliasAssumptions(OS);
1474   printStatements(OS.indent(4));
1475 }
1476 
1477 void Scop::dump() const { print(dbgs()); }
1478 
1479 isl_ctx *Scop::getIslCtx() const { return IslCtx; }
1480 
1481 __isl_give isl_union_set *Scop::getDomains() {
1482   isl_union_set *Domain = isl_union_set_empty(getParamSpace());
1483 
1484   for (ScopStmt *Stmt : *this)
1485     Domain = isl_union_set_add_set(Domain, Stmt->getDomain());
1486 
1487   return Domain;
1488 }
1489 
1490 __isl_give isl_union_map *Scop::getMustWrites() {
1491   isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
1492 
1493   for (ScopStmt *Stmt : *this) {
1494     for (MemoryAccess *MA : *Stmt) {
1495       if (!MA->isMustWrite())
1496         continue;
1497 
1498       isl_set *Domain = Stmt->getDomain();
1499       isl_map *AccessDomain = MA->getAccessRelation();
1500       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1501       Write = isl_union_map_add_map(Write, AccessDomain);
1502     }
1503   }
1504   return isl_union_map_coalesce(Write);
1505 }
1506 
1507 __isl_give isl_union_map *Scop::getMayWrites() {
1508   isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
1509 
1510   for (ScopStmt *Stmt : *this) {
1511     for (MemoryAccess *MA : *Stmt) {
1512       if (!MA->isMayWrite())
1513         continue;
1514 
1515       isl_set *Domain = Stmt->getDomain();
1516       isl_map *AccessDomain = MA->getAccessRelation();
1517       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1518       Write = isl_union_map_add_map(Write, AccessDomain);
1519     }
1520   }
1521   return isl_union_map_coalesce(Write);
1522 }
1523 
1524 __isl_give isl_union_map *Scop::getWrites() {
1525   isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
1526 
1527   for (ScopStmt *Stmt : *this) {
1528     for (MemoryAccess *MA : *Stmt) {
1529       if (!MA->isWrite())
1530         continue;
1531 
1532       isl_set *Domain = Stmt->getDomain();
1533       isl_map *AccessDomain = MA->getAccessRelation();
1534       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1535       Write = isl_union_map_add_map(Write, AccessDomain);
1536     }
1537   }
1538   return isl_union_map_coalesce(Write);
1539 }
1540 
1541 __isl_give isl_union_map *Scop::getReads() {
1542   isl_union_map *Read = isl_union_map_empty(getParamSpace());
1543 
1544   for (ScopStmt *Stmt : *this) {
1545     for (MemoryAccess *MA : *Stmt) {
1546       if (!MA->isRead())
1547         continue;
1548 
1549       isl_set *Domain = Stmt->getDomain();
1550       isl_map *AccessDomain = MA->getAccessRelation();
1551 
1552       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1553       Read = isl_union_map_add_map(Read, AccessDomain);
1554     }
1555   }
1556   return isl_union_map_coalesce(Read);
1557 }
1558 
1559 __isl_give isl_union_map *Scop::getSchedule() {
1560   isl_union_map *Schedule = isl_union_map_empty(getParamSpace());
1561 
1562   for (ScopStmt *Stmt : *this)
1563     Schedule = isl_union_map_add_map(Schedule, Stmt->getScattering());
1564 
1565   return isl_union_map_coalesce(Schedule);
1566 }
1567 
1568 bool Scop::restrictDomains(__isl_take isl_union_set *Domain) {
1569   bool Changed = false;
1570   for (ScopStmt *Stmt : *this) {
1571     isl_union_set *StmtDomain = isl_union_set_from_set(Stmt->getDomain());
1572     isl_union_set *NewStmtDomain = isl_union_set_intersect(
1573         isl_union_set_copy(StmtDomain), isl_union_set_copy(Domain));
1574 
1575     if (isl_union_set_is_subset(StmtDomain, NewStmtDomain)) {
1576       isl_union_set_free(StmtDomain);
1577       isl_union_set_free(NewStmtDomain);
1578       continue;
1579     }
1580 
1581     Changed = true;
1582 
1583     isl_union_set_free(StmtDomain);
1584     NewStmtDomain = isl_union_set_coalesce(NewStmtDomain);
1585 
1586     if (isl_union_set_is_empty(NewStmtDomain)) {
1587       Stmt->restrictDomain(isl_set_empty(Stmt->getDomainSpace()));
1588       isl_union_set_free(NewStmtDomain);
1589     } else
1590       Stmt->restrictDomain(isl_set_from_union_set(NewStmtDomain));
1591   }
1592   isl_union_set_free(Domain);
1593   return Changed;
1594 }
1595 
1596 ScalarEvolution *Scop::getSE() const { return SE; }
1597 
1598 bool Scop::isTrivialBB(BasicBlock *BB, TempScop &tempScop) {
1599   if (tempScop.getAccessFunctions(BB))
1600     return false;
1601 
1602   return true;
1603 }
1604 
1605 void Scop::buildScop(TempScop &tempScop, const Region &CurRegion,
1606                      SmallVectorImpl<Loop *> &NestLoops,
1607                      SmallVectorImpl<unsigned> &Scatter, LoopInfo &LI) {
1608   Loop *L = castToLoop(CurRegion, LI);
1609 
1610   if (L)
1611     NestLoops.push_back(L);
1612 
1613   unsigned loopDepth = NestLoops.size();
1614   assert(Scatter.size() > loopDepth && "Scatter not big enough!");
1615 
1616   for (Region::const_element_iterator I = CurRegion.element_begin(),
1617                                       E = CurRegion.element_end();
1618        I != E; ++I)
1619     if (I->isSubRegion())
1620       buildScop(tempScop, *(I->getNodeAs<Region>()), NestLoops, Scatter, LI);
1621     else {
1622       BasicBlock *BB = I->getNodeAs<BasicBlock>();
1623 
1624       if (isTrivialBB(BB, tempScop))
1625         continue;
1626 
1627       Stmts.push_back(
1628           new ScopStmt(*this, tempScop, CurRegion, *BB, NestLoops, Scatter));
1629 
1630       // Increasing the Scattering function is OK for the moment, because
1631       // we are using a depth first iterator and the program is well structured.
1632       ++Scatter[loopDepth];
1633     }
1634 
1635   if (!L)
1636     return;
1637 
1638   // Exiting a loop region.
1639   Scatter[loopDepth] = 0;
1640   NestLoops.pop_back();
1641   ++Scatter[loopDepth - 1];
1642 }
1643 
1644 //===----------------------------------------------------------------------===//
1645 ScopInfo::ScopInfo() : RegionPass(ID), scop(0) {
1646   ctx = isl_ctx_alloc();
1647   isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
1648 }
1649 
1650 ScopInfo::~ScopInfo() {
1651   clear();
1652   isl_ctx_free(ctx);
1653 }
1654 
1655 void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
1656   AU.addRequired<LoopInfo>();
1657   AU.addRequired<RegionInfoPass>();
1658   AU.addRequired<ScalarEvolution>();
1659   AU.addRequired<TempScopInfo>();
1660   AU.addRequired<AliasAnalysis>();
1661   AU.setPreservesAll();
1662 }
1663 
1664 bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
1665   LoopInfo &LI = getAnalysis<LoopInfo>();
1666   AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
1667   ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
1668 
1669   TempScop *tempScop = getAnalysis<TempScopInfo>().getTempScop(R);
1670 
1671   // This region is no Scop.
1672   if (!tempScop) {
1673     scop = 0;
1674     return false;
1675   }
1676 
1677   // Statistics.
1678   ++ScopFound;
1679   if (tempScop->getMaxLoopDepth() > 0)
1680     ++RichScopFound;
1681 
1682   scop = new Scop(*tempScop, LI, SE, ctx);
1683 
1684   if (!PollyUseRuntimeAliasChecks)
1685     return false;
1686 
1687   // If a problem occurs while building the alias groups we need to delete
1688   // this SCoP and pretend it wasn't valid in the first place.
1689   if (scop->buildAliasGroups(AA))
1690     return false;
1691 
1692   --ScopFound;
1693   if (tempScop->getMaxLoopDepth() > 0)
1694     --RichScopFound;
1695 
1696   DEBUG(dbgs()
1697         << "\n\nNOTE: Run time checks for " << scop->getNameStr()
1698         << " could not be created as the number of parameters involved is too "
1699            "high. The SCoP will be "
1700            "dismissed.\nUse:\n\t--polly-rtc-max-parameters=X\nto adjust the "
1701            "maximal number of parameters but be advised that the compile time "
1702            "might increase exponentially.\n\n");
1703 
1704   delete scop;
1705   scop = nullptr;
1706   return false;
1707 }
1708 
1709 char ScopInfo::ID = 0;
1710 
1711 Pass *polly::createScopInfoPass() { return new ScopInfo(); }
1712 
1713 INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops",
1714                       "Polly - Create polyhedral description of Scops", false,
1715                       false);
1716 INITIALIZE_AG_DEPENDENCY(AliasAnalysis);
1717 INITIALIZE_PASS_DEPENDENCY(LoopInfo);
1718 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
1719 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
1720 INITIALIZE_PASS_DEPENDENCY(TempScopInfo);
1721 INITIALIZE_PASS_END(ScopInfo, "polly-scops",
1722                     "Polly - Create polyhedral description of Scops", false,
1723                     false)
1724