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 representation is shared among several tools in the polyhedral
16 // community, which are e.g. Cloog, Pluto, Loopo, Graphite.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #include "polly/LinkAllPasses.h"
21 #include "polly/Options.h"
22 #include "polly/ScopInfo.h"
23 #include "polly/Support/GICHelper.h"
24 #include "polly/Support/SCEVValidator.h"
25 #include "polly/Support/ScopHelper.h"
26 #include "polly/TempScopInfo.h"
27 #include "llvm/ADT/MapVector.h"
28 #include "llvm/ADT/SetVector.h"
29 #include "llvm/ADT/Statistic.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/StringExtras.h"
32 #include "llvm/Analysis/AliasAnalysis.h"
33 #include "llvm/Analysis/LoopInfo.h"
34 #include "llvm/Analysis/RegionIterator.h"
35 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
36 #include "llvm/Support/Debug.h"
37 #include "isl/aff.h"
38 #include "isl/constraint.h"
39 #include "isl/local_space.h"
40 #include "isl/map.h"
41 #include "isl/options.h"
42 #include "isl/printer.h"
43 #include "isl/schedule.h"
44 #include "isl/schedule_node.h"
45 #include "isl/set.h"
46 #include "isl/union_map.h"
47 #include "isl/union_set.h"
48 #include "isl/val.h"
49 #include <sstream>
50 #include <string>
51 #include <vector>
52 
53 using namespace llvm;
54 using namespace polly;
55 
56 #define DEBUG_TYPE "polly-scops"
57 
58 STATISTIC(ScopFound, "Number of valid Scops");
59 STATISTIC(RichScopFound, "Number of Scops containing a loop");
60 
61 // Multiplicative reductions can be disabled separately as these kind of
62 // operations can overflow easily. Additive reductions and bit operations
63 // are in contrast pretty stable.
64 static cl::opt<bool> DisableMultiplicativeReductions(
65     "polly-disable-multiplicative-reductions",
66     cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore,
67     cl::init(false), cl::cat(PollyCategory));
68 
69 static cl::opt<unsigned> RunTimeChecksMaxParameters(
70     "polly-rtc-max-parameters",
71     cl::desc("The maximal number of parameters allowed in RTCs."), cl::Hidden,
72     cl::ZeroOrMore, cl::init(8), cl::cat(PollyCategory));
73 
74 static cl::opt<unsigned> RunTimeChecksMaxArraysPerGroup(
75     "polly-rtc-max-arrays-per-group",
76     cl::desc("The maximal number of arrays to compare in each alias group."),
77     cl::Hidden, cl::ZeroOrMore, cl::init(20), cl::cat(PollyCategory));
78 
79 /// Translate a 'const SCEV *' expression in an isl_pw_aff.
80 struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
81 public:
82   /// @brief Translate a 'const SCEV *' to an isl_pw_aff.
83   ///
84   /// @param Stmt The location at which the scalar evolution expression
85   ///             is evaluated.
86   /// @param Expr The expression that is translated.
87   static __isl_give isl_pw_aff *getPwAff(ScopStmt *Stmt, const SCEV *Expr);
88 
89 private:
90   isl_ctx *Ctx;
91   int NbLoopSpaces;
92   const Scop *S;
93 
94   SCEVAffinator(const ScopStmt *Stmt);
95   int getLoopDepth(const Loop *L);
96 
97   __isl_give isl_pw_aff *visit(const SCEV *Expr);
98   __isl_give isl_pw_aff *visitConstant(const SCEVConstant *Expr);
99   __isl_give isl_pw_aff *visitTruncateExpr(const SCEVTruncateExpr *Expr);
100   __isl_give isl_pw_aff *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr);
101   __isl_give isl_pw_aff *visitSignExtendExpr(const SCEVSignExtendExpr *Expr);
102   __isl_give isl_pw_aff *visitAddExpr(const SCEVAddExpr *Expr);
103   __isl_give isl_pw_aff *visitMulExpr(const SCEVMulExpr *Expr);
104   __isl_give isl_pw_aff *visitUDivExpr(const SCEVUDivExpr *Expr);
105   __isl_give isl_pw_aff *visitAddRecExpr(const SCEVAddRecExpr *Expr);
106   __isl_give isl_pw_aff *visitSMaxExpr(const SCEVSMaxExpr *Expr);
107   __isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr);
108   __isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr);
109   __isl_give isl_pw_aff *visitSDivInstruction(Instruction *SDiv);
110   __isl_give isl_pw_aff *visitSRemInstruction(Instruction *SDiv);
111 
112   friend struct SCEVVisitor<SCEVAffinator, isl_pw_aff *>;
113 };
114 
115 SCEVAffinator::SCEVAffinator(const ScopStmt *Stmt)
116     : Ctx(Stmt->getIslCtx()), NbLoopSpaces(Stmt->getNumIterators()),
117       S(Stmt->getParent()) {}
118 
119 __isl_give isl_pw_aff *SCEVAffinator::getPwAff(ScopStmt *Stmt,
120                                                const SCEV *Scev) {
121   Scop *S = Stmt->getParent();
122   const Region *Reg = &S->getRegion();
123 
124   S->addParams(getParamsInAffineExpr(Reg, Scev, *S->getSE()));
125 
126   SCEVAffinator Affinator(Stmt);
127   return Affinator.visit(Scev);
128 }
129 
130 __isl_give isl_pw_aff *SCEVAffinator::visit(const SCEV *Expr) {
131   // In case the scev is a valid parameter, we do not further analyze this
132   // expression, but create a new parameter in the isl_pw_aff. This allows us
133   // to treat subexpressions that we cannot translate into an piecewise affine
134   // expression, as constant parameters of the piecewise affine expression.
135   if (isl_id *Id = S->getIdForParam(Expr)) {
136     isl_space *Space = isl_space_set_alloc(Ctx, 1, NbLoopSpaces);
137     Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
138 
139     isl_set *Domain = isl_set_universe(isl_space_copy(Space));
140     isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space));
141     Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
142 
143     return isl_pw_aff_alloc(Domain, Affine);
144   }
145 
146   return SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Expr);
147 }
148 
149 __isl_give isl_pw_aff *SCEVAffinator::visitConstant(const SCEVConstant *Expr) {
150   ConstantInt *Value = Expr->getValue();
151   isl_val *v;
152 
153   // LLVM does not define if an integer value is interpreted as a signed or
154   // unsigned value. Hence, without further information, it is unknown how
155   // this value needs to be converted to GMP. At the moment, we only support
156   // signed operations. So we just interpret it as signed. Later, there are
157   // two options:
158   //
159   // 1. We always interpret any value as signed and convert the values on
160   //    demand.
161   // 2. We pass down the signedness of the calculation and use it to interpret
162   //    this constant correctly.
163   v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
164 
165   isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
166   isl_local_space *ls = isl_local_space_from_space(Space);
167   return isl_pw_aff_from_aff(isl_aff_val_on_domain(ls, v));
168 }
169 
170 __isl_give isl_pw_aff *
171 SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
172   llvm_unreachable("SCEVTruncateExpr not yet supported");
173 }
174 
175 __isl_give isl_pw_aff *
176 SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
177   llvm_unreachable("SCEVZeroExtendExpr not yet supported");
178 }
179 
180 __isl_give isl_pw_aff *
181 SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
182   // Assuming the value is signed, a sign extension is basically a noop.
183   // TODO: Reconsider this as soon as we support unsigned values.
184   return visit(Expr->getOperand());
185 }
186 
187 __isl_give isl_pw_aff *SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
188   isl_pw_aff *Sum = visit(Expr->getOperand(0));
189 
190   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
191     isl_pw_aff *NextSummand = visit(Expr->getOperand(i));
192     Sum = isl_pw_aff_add(Sum, NextSummand);
193   }
194 
195   // TODO: Check for NSW and NUW.
196 
197   return Sum;
198 }
199 
200 __isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) {
201   // Divide Expr into a constant part and the rest. Then visit both and multiply
202   // the result to obtain the representation for Expr. While the second part of
203   // ConstantAndLeftOverPair might still be a SCEVMulExpr we will not get to
204   // this point again. The reason is that if it is a multiplication it consists
205   // only of parameters and we will stop in the visit(const SCEV *) function and
206   // return the isl_pw_aff for that parameter.
207   auto ConstantAndLeftOverPair = extractConstantFactor(Expr, *S->getSE());
208   return isl_pw_aff_mul(visit(ConstantAndLeftOverPair.first),
209                         visit(ConstantAndLeftOverPair.second));
210 }
211 
212 __isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) {
213   llvm_unreachable("SCEVUDivExpr not yet supported");
214 }
215 
216 __isl_give isl_pw_aff *
217 SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
218   assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
219 
220   auto Flags = Expr->getNoWrapFlags();
221 
222   // Directly generate isl_pw_aff for Expr if 'start' is zero.
223   if (Expr->getStart()->isZero()) {
224     assert(S->getRegion().contains(Expr->getLoop()) &&
225            "Scop does not contain the loop referenced in this AddRec");
226 
227     isl_pw_aff *Start = visit(Expr->getStart());
228     isl_pw_aff *Step = visit(Expr->getOperand(1));
229     isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
230     isl_local_space *LocalSpace = isl_local_space_from_space(Space);
231 
232     int loopDimension = getLoopDepth(Expr->getLoop());
233 
234     isl_aff *LAff = isl_aff_set_coefficient_si(
235         isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
236     isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
237 
238     // TODO: Do we need to check for NSW and NUW?
239     return isl_pw_aff_add(Start, isl_pw_aff_mul(Step, LPwAff));
240   }
241 
242   // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
243   // if 'start' is not zero.
244   // TODO: Using the original SCEV no-wrap flags is not always safe, however
245   //       as our code generation is reordering the expression anyway it doesn't
246   //       really matter.
247   ScalarEvolution &SE = *S->getSE();
248   const SCEV *ZeroStartExpr =
249       SE.getAddRecExpr(SE.getConstant(Expr->getStart()->getType(), 0),
250                        Expr->getStepRecurrence(SE), Expr->getLoop(), Flags);
251 
252   isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr);
253   isl_pw_aff *Start = visit(Expr->getStart());
254 
255   return isl_pw_aff_add(ZeroStartResult, Start);
256 }
257 
258 __isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) {
259   isl_pw_aff *Max = visit(Expr->getOperand(0));
260 
261   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
262     isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
263     Max = isl_pw_aff_max(Max, NextOperand);
264   }
265 
266   return Max;
267 }
268 
269 __isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) {
270   llvm_unreachable("SCEVUMaxExpr not yet supported");
271 }
272 
273 __isl_give isl_pw_aff *SCEVAffinator::visitSDivInstruction(Instruction *SDiv) {
274   assert(SDiv->getOpcode() == Instruction::SDiv && "Assumed SDiv instruction!");
275   auto *SE = S->getSE();
276 
277   auto *Divisor = SDiv->getOperand(1);
278   auto *DivisorSCEV = SE->getSCEV(Divisor);
279   auto *DivisorPWA = visit(DivisorSCEV);
280   assert(isa<ConstantInt>(Divisor) &&
281          "SDiv is no parameter but has a non-constant RHS.");
282 
283   auto *Dividend = SDiv->getOperand(0);
284   auto *DividendSCEV = SE->getSCEV(Dividend);
285   auto *DividendPWA = visit(DividendSCEV);
286   return isl_pw_aff_tdiv_q(DividendPWA, DivisorPWA);
287 }
288 
289 __isl_give isl_pw_aff *SCEVAffinator::visitSRemInstruction(Instruction *SRem) {
290   assert(SRem->getOpcode() == Instruction::SRem && "Assumed SRem instruction!");
291   auto *SE = S->getSE();
292 
293   auto *Divisor = dyn_cast<ConstantInt>(SRem->getOperand(1));
294   assert(Divisor && "SRem is no parameter but has a non-constant RHS.");
295   auto *DivisorVal = isl_valFromAPInt(Ctx, Divisor->getValue(),
296                                       /* isSigned */ true);
297 
298   auto *Dividend = SRem->getOperand(0);
299   auto *DividendSCEV = SE->getSCEV(Dividend);
300   auto *DividendPWA = visit(DividendSCEV);
301 
302   return isl_pw_aff_mod_val(DividendPWA, isl_val_abs(DivisorVal));
303 }
304 
305 __isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) {
306   if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) {
307     switch (I->getOpcode()) {
308     case Instruction::SDiv:
309       return visitSDivInstruction(I);
310     case Instruction::SRem:
311       return visitSRemInstruction(I);
312     default:
313       break; // Fall through.
314     }
315   }
316 
317   llvm_unreachable(
318       "Unknowns SCEV was neither parameter nor a valid instruction.");
319 }
320 
321 int SCEVAffinator::getLoopDepth(const Loop *L) {
322   Loop *outerLoop = S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L));
323   assert(outerLoop && "Scop does not contain this loop");
324   return L->getLoopDepth() - outerLoop->getLoopDepth();
325 }
326 
327 /// @brief Add the bounds of @p Range to the set @p S for dimension @p dim.
328 static __isl_give isl_set *addRangeBoundsToSet(__isl_take isl_set *S,
329                                                const ConstantRange &Range,
330                                                int dim,
331                                                enum isl_dim_type type) {
332   isl_val *V;
333   isl_ctx *ctx = isl_set_get_ctx(S);
334 
335   bool useLowerUpperBound = Range.isSignWrappedSet() && !Range.isFullSet();
336   const auto LB = useLowerUpperBound ? Range.getLower() : Range.getSignedMin();
337   V = isl_valFromAPInt(ctx, LB, true);
338   isl_set *SLB = isl_set_lower_bound_val(isl_set_copy(S), type, dim, V);
339 
340   const auto UB = useLowerUpperBound ? Range.getUpper() : Range.getSignedMax();
341   V = isl_valFromAPInt(ctx, UB, true);
342   if (useLowerUpperBound)
343     V = isl_val_sub_ui(V, 1);
344   isl_set *SUB = isl_set_upper_bound_val(S, type, dim, V);
345 
346   if (useLowerUpperBound)
347     return isl_set_union(SLB, SUB);
348   else
349     return isl_set_intersect(SLB, SUB);
350 }
351 
352 ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx,
353                              const SmallVector<const SCEV *, 4> &DimensionSizes,
354                              bool IsPHI)
355     : BasePtr(BasePtr), ElementType(ElementType),
356       DimensionSizes(DimensionSizes), IsPHI(IsPHI) {
357   std::string BasePtrName =
358       getIslCompatibleName("MemRef_", BasePtr, IsPHI ? "__phi" : "");
359   Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
360 }
361 
362 ScopArrayInfo::~ScopArrayInfo() { isl_id_free(Id); }
363 
364 std::string ScopArrayInfo::getName() const { return isl_id_get_name(Id); }
365 
366 int ScopArrayInfo::getElemSizeInBytes() const {
367   return ElementType->getPrimitiveSizeInBits() / 8;
368 }
369 
370 isl_id *ScopArrayInfo::getBasePtrId() const { return isl_id_copy(Id); }
371 
372 void ScopArrayInfo::dump() const { print(errs()); }
373 
374 void ScopArrayInfo::print(raw_ostream &OS) const {
375   OS.indent(8) << *getElementType() << " " << getName() << "[*]";
376   for (unsigned u = 0; u < getNumberOfDimensions(); u++)
377     OS << "[" << *DimensionSizes[u] << "]";
378   OS << " // Element size " << getElemSizeInBytes() << "\n";
379 }
380 
381 const ScopArrayInfo *
382 ScopArrayInfo::getFromAccessFunction(__isl_keep isl_pw_multi_aff *PMA) {
383   isl_id *Id = isl_pw_multi_aff_get_tuple_id(PMA, isl_dim_out);
384   assert(Id && "Output dimension didn't have an ID");
385   return getFromId(Id);
386 }
387 
388 const ScopArrayInfo *ScopArrayInfo::getFromId(isl_id *Id) {
389   void *User = isl_id_get_user(Id);
390   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
391   isl_id_free(Id);
392   return SAI;
393 }
394 
395 const std::string
396 MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
397   switch (RT) {
398   case MemoryAccess::RT_NONE:
399     llvm_unreachable("Requested a reduction operator string for a memory "
400                      "access which isn't a reduction");
401   case MemoryAccess::RT_ADD:
402     return "+";
403   case MemoryAccess::RT_MUL:
404     return "*";
405   case MemoryAccess::RT_BOR:
406     return "|";
407   case MemoryAccess::RT_BXOR:
408     return "^";
409   case MemoryAccess::RT_BAND:
410     return "&";
411   }
412   llvm_unreachable("Unknown reduction type");
413   return "";
414 }
415 
416 /// @brief Return the reduction type for a given binary operator
417 static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp,
418                                                     const Instruction *Load) {
419   if (!BinOp)
420     return MemoryAccess::RT_NONE;
421   switch (BinOp->getOpcode()) {
422   case Instruction::FAdd:
423     if (!BinOp->hasUnsafeAlgebra())
424       return MemoryAccess::RT_NONE;
425   // Fall through
426   case Instruction::Add:
427     return MemoryAccess::RT_ADD;
428   case Instruction::Or:
429     return MemoryAccess::RT_BOR;
430   case Instruction::Xor:
431     return MemoryAccess::RT_BXOR;
432   case Instruction::And:
433     return MemoryAccess::RT_BAND;
434   case Instruction::FMul:
435     if (!BinOp->hasUnsafeAlgebra())
436       return MemoryAccess::RT_NONE;
437   // Fall through
438   case Instruction::Mul:
439     if (DisableMultiplicativeReductions)
440       return MemoryAccess::RT_NONE;
441     return MemoryAccess::RT_MUL;
442   default:
443     return MemoryAccess::RT_NONE;
444   }
445 }
446 //===----------------------------------------------------------------------===//
447 
448 MemoryAccess::~MemoryAccess() {
449   isl_id_free(Id);
450   isl_map_free(AccessRelation);
451   isl_map_free(newAccessRelation);
452 }
453 
454 static MemoryAccess::AccessType getMemoryAccessType(const IRAccess &Access) {
455   switch (Access.getType()) {
456   case IRAccess::READ:
457     return MemoryAccess::READ;
458   case IRAccess::MUST_WRITE:
459     return MemoryAccess::MUST_WRITE;
460   case IRAccess::MAY_WRITE:
461     return MemoryAccess::MAY_WRITE;
462   }
463   llvm_unreachable("Unknown IRAccess type!");
464 }
465 
466 const ScopArrayInfo *MemoryAccess::getScopArrayInfo() const {
467   isl_id *ArrayId = getArrayId();
468   void *User = isl_id_get_user(ArrayId);
469   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
470   isl_id_free(ArrayId);
471   return SAI;
472 }
473 
474 __isl_give isl_id *MemoryAccess::getArrayId() const {
475   return isl_map_get_tuple_id(AccessRelation, isl_dim_out);
476 }
477 
478 __isl_give isl_pw_multi_aff *MemoryAccess::applyScheduleToAccessRelation(
479     __isl_take isl_union_map *USchedule) const {
480   isl_map *Schedule, *ScheduledAccRel;
481   isl_union_set *UDomain;
482 
483   UDomain = isl_union_set_from_set(getStatement()->getDomain());
484   USchedule = isl_union_map_intersect_domain(USchedule, UDomain);
485   Schedule = isl_map_from_union_map(USchedule);
486   ScheduledAccRel = isl_map_apply_domain(getAccessRelation(), Schedule);
487   return isl_pw_multi_aff_from_map(ScheduledAccRel);
488 }
489 
490 __isl_give isl_map *MemoryAccess::getOriginalAccessRelation() const {
491   return isl_map_copy(AccessRelation);
492 }
493 
494 std::string MemoryAccess::getOriginalAccessRelationStr() const {
495   return stringFromIslObj(AccessRelation);
496 }
497 
498 __isl_give isl_space *MemoryAccess::getOriginalAccessRelationSpace() const {
499   return isl_map_get_space(AccessRelation);
500 }
501 
502 __isl_give isl_map *MemoryAccess::getNewAccessRelation() const {
503   return isl_map_copy(newAccessRelation);
504 }
505 
506 __isl_give isl_basic_map *
507 MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
508   isl_space *Space = isl_space_set_alloc(Statement->getIslCtx(), 0, 1);
509   Space = isl_space_align_params(Space, Statement->getDomainSpace());
510 
511   return isl_basic_map_from_domain_and_range(
512       isl_basic_set_universe(Statement->getDomainSpace()),
513       isl_basic_set_universe(Space));
514 }
515 
516 // Formalize no out-of-bound access assumption
517 //
518 // When delinearizing array accesses we optimistically assume that the
519 // delinearized accesses do not access out of bound locations (the subscript
520 // expression of each array evaluates for each statement instance that is
521 // executed to a value that is larger than zero and strictly smaller than the
522 // size of the corresponding dimension). The only exception is the outermost
523 // dimension for which we do not need to assume any upper bound.  At this point
524 // we formalize this assumption to ensure that at code generation time the
525 // relevant run-time checks can be generated.
526 //
527 // To find the set of constraints necessary to avoid out of bound accesses, we
528 // first build the set of data locations that are not within array bounds. We
529 // then apply the reverse access relation to obtain the set of iterations that
530 // may contain invalid accesses and reduce this set of iterations to the ones
531 // that are actually executed by intersecting them with the domain of the
532 // statement. If we now project out all loop dimensions, we obtain a set of
533 // parameters that may cause statement instances to be executed that may
534 // possibly yield out of bound memory accesses. The complement of these
535 // constraints is the set of constraints that needs to be assumed to ensure such
536 // statement instances are never executed.
537 void MemoryAccess::assumeNoOutOfBound(const IRAccess &Access) {
538   isl_space *Space = isl_space_range(getOriginalAccessRelationSpace());
539   isl_set *Outside = isl_set_empty(isl_space_copy(Space));
540   for (int i = 1, Size = Access.Subscripts.size(); i < Size; ++i) {
541     isl_local_space *LS = isl_local_space_from_space(isl_space_copy(Space));
542     isl_pw_aff *Var =
543         isl_pw_aff_var_on_domain(isl_local_space_copy(LS), isl_dim_set, i);
544     isl_pw_aff *Zero = isl_pw_aff_zero_on_domain(LS);
545 
546     isl_set *DimOutside;
547 
548     DimOutside = isl_pw_aff_lt_set(isl_pw_aff_copy(Var), Zero);
549     isl_pw_aff *SizeE = SCEVAffinator::getPwAff(Statement, Access.Sizes[i - 1]);
550 
551     SizeE = isl_pw_aff_drop_dims(SizeE, isl_dim_in, 0,
552                                  Statement->getNumIterators());
553     SizeE = isl_pw_aff_add_dims(SizeE, isl_dim_in,
554                                 isl_space_dim(Space, isl_dim_set));
555     SizeE = isl_pw_aff_set_tuple_id(SizeE, isl_dim_in,
556                                     isl_space_get_tuple_id(Space, isl_dim_set));
557 
558     DimOutside = isl_set_union(DimOutside, isl_pw_aff_le_set(SizeE, Var));
559 
560     Outside = isl_set_union(Outside, DimOutside);
561   }
562 
563   Outside = isl_set_apply(Outside, isl_map_reverse(getAccessRelation()));
564   Outside = isl_set_intersect(Outside, Statement->getDomain());
565   Outside = isl_set_params(Outside);
566 
567   // Remove divs to avoid the construction of overly complicated assumptions.
568   // Doing so increases the set of parameter combinations that are assumed to
569   // not appear. This is always save, but may make the resulting run-time check
570   // bail out more often than strictly necessary.
571   Outside = isl_set_remove_divs(Outside);
572   Outside = isl_set_complement(Outside);
573   Statement->getParent()->addAssumption(Outside);
574   isl_space_free(Space);
575 }
576 
577 void MemoryAccess::computeBoundsOnAccessRelation(unsigned ElementSize) {
578   ScalarEvolution *SE = Statement->getParent()->getSE();
579 
580   Value *Ptr = getPointerOperand(*getAccessInstruction());
581   if (!Ptr || !SE->isSCEVable(Ptr->getType()))
582     return;
583 
584   auto *PtrSCEV = SE->getSCEV(Ptr);
585   if (isa<SCEVCouldNotCompute>(PtrSCEV))
586     return;
587 
588   auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
589   if (BasePtrSCEV && !isa<SCEVCouldNotCompute>(BasePtrSCEV))
590     PtrSCEV = SE->getMinusSCEV(PtrSCEV, BasePtrSCEV);
591 
592   const ConstantRange &Range = SE->getSignedRange(PtrSCEV);
593   if (Range.isFullSet())
594     return;
595 
596   bool isWrapping = Range.isSignWrappedSet();
597   unsigned BW = Range.getBitWidth();
598   const auto LB = isWrapping ? Range.getLower() : Range.getSignedMin();
599   const auto UB = isWrapping ? Range.getUpper() : Range.getSignedMax();
600 
601   auto Min = LB.sdiv(APInt(BW, ElementSize));
602   auto Max = (UB - APInt(BW, 1)).sdiv(APInt(BW, ElementSize));
603 
604   isl_set *AccessRange = isl_map_range(isl_map_copy(AccessRelation));
605   AccessRange =
606       addRangeBoundsToSet(AccessRange, ConstantRange(Min, Max), 0, isl_dim_set);
607   AccessRelation = isl_map_intersect_range(AccessRelation, AccessRange);
608 }
609 
610 __isl_give isl_map *MemoryAccess::foldAccess(const IRAccess &Access,
611                                              __isl_take isl_map *AccessRelation,
612                                              ScopStmt *Statement) {
613   int Size = Access.Subscripts.size();
614 
615   for (int i = Size - 2; i >= 0; --i) {
616     isl_space *Space;
617     isl_map *MapOne, *MapTwo;
618     isl_pw_aff *DimSize = SCEVAffinator::getPwAff(Statement, Access.Sizes[i]);
619 
620     isl_space *SpaceSize = isl_pw_aff_get_space(DimSize);
621     isl_pw_aff_free(DimSize);
622     isl_id *ParamId = isl_space_get_dim_id(SpaceSize, isl_dim_param, 0);
623 
624     Space = isl_map_get_space(AccessRelation);
625     Space = isl_space_map_from_set(isl_space_range(Space));
626     Space = isl_space_align_params(Space, SpaceSize);
627 
628     int ParamLocation = isl_space_find_dim_by_id(Space, isl_dim_param, ParamId);
629     isl_id_free(ParamId);
630 
631     MapOne = isl_map_universe(isl_space_copy(Space));
632     for (int j = 0; j < Size; ++j)
633       MapOne = isl_map_equate(MapOne, isl_dim_in, j, isl_dim_out, j);
634     MapOne = isl_map_lower_bound_si(MapOne, isl_dim_in, i + 1, 0);
635 
636     MapTwo = isl_map_universe(isl_space_copy(Space));
637     for (int j = 0; j < Size; ++j)
638       if (j < i || j > i + 1)
639         MapTwo = isl_map_equate(MapTwo, isl_dim_in, j, isl_dim_out, j);
640 
641     isl_local_space *LS = isl_local_space_from_space(Space);
642     isl_constraint *C;
643     C = isl_equality_alloc(isl_local_space_copy(LS));
644     C = isl_constraint_set_constant_si(C, -1);
645     C = isl_constraint_set_coefficient_si(C, isl_dim_in, i, 1);
646     C = isl_constraint_set_coefficient_si(C, isl_dim_out, i, -1);
647     MapTwo = isl_map_add_constraint(MapTwo, C);
648     C = isl_equality_alloc(LS);
649     C = isl_constraint_set_coefficient_si(C, isl_dim_in, i + 1, 1);
650     C = isl_constraint_set_coefficient_si(C, isl_dim_out, i + 1, -1);
651     C = isl_constraint_set_coefficient_si(C, isl_dim_param, ParamLocation, 1);
652     MapTwo = isl_map_add_constraint(MapTwo, C);
653     MapTwo = isl_map_upper_bound_si(MapTwo, isl_dim_in, i + 1, -1);
654 
655     MapOne = isl_map_union(MapOne, MapTwo);
656     AccessRelation = isl_map_apply_range(AccessRelation, MapOne);
657   }
658   return AccessRelation;
659 }
660 
661 MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst,
662                            ScopStmt *Statement, const ScopArrayInfo *SAI,
663                            int Identifier)
664     : AccType(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst),
665       newAccessRelation(nullptr) {
666 
667   isl_ctx *Ctx = Statement->getIslCtx();
668   BaseAddr = Access.getBase();
669   BaseName = getIslCompatibleName("MemRef_", getBaseAddr(), "");
670 
671   isl_id *BaseAddrId = SAI->getBasePtrId();
672 
673   auto IdName = "__polly_array_ref_ " + std::to_string(Identifier);
674   Id = isl_id_alloc(Ctx, IdName.c_str(), nullptr);
675 
676   if (!Access.isAffine()) {
677     // We overapproximate non-affine accesses with a possible access to the
678     // whole array. For read accesses it does not make a difference, if an
679     // access must or may happen. However, for write accesses it is important to
680     // differentiate between writes that must happen and writes that may happen.
681     AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
682     AccessRelation =
683         isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
684 
685     computeBoundsOnAccessRelation(Access.getElemSizeInBytes());
686     return;
687   }
688 
689   isl_space *Space = isl_space_alloc(Ctx, 0, Statement->getNumIterators(), 0);
690   AccessRelation = isl_map_universe(Space);
691 
692   for (int i = 0, Size = Access.Subscripts.size(); i < Size; ++i) {
693     isl_pw_aff *Affine =
694         SCEVAffinator::getPwAff(Statement, Access.Subscripts[i]);
695 
696     if (Size == 1) {
697       // For the non delinearized arrays, divide the access function of the last
698       // subscript by the size of the elements in the array.
699       //
700       // A stride one array access in C expressed as A[i] is expressed in
701       // LLVM-IR as something like A[i * elementsize]. This hides the fact that
702       // two subsequent values of 'i' index two values that are stored next to
703       // each other in memory. By this division we make this characteristic
704       // obvious again.
705       isl_val *v = isl_val_int_from_si(Ctx, Access.getElemSizeInBytes());
706       Affine = isl_pw_aff_scale_down_val(Affine, v);
707     }
708 
709     isl_map *SubscriptMap = isl_map_from_pw_aff(Affine);
710 
711     AccessRelation = isl_map_flat_range_product(AccessRelation, SubscriptMap);
712   }
713 
714   AccessRelation = foldAccess(Access, AccessRelation, Statement);
715 
716   Space = Statement->getDomainSpace();
717   AccessRelation = isl_map_set_tuple_id(
718       AccessRelation, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
719   AccessRelation =
720       isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
721 
722   assumeNoOutOfBound(Access);
723   AccessRelation = isl_map_gist_domain(AccessRelation, Statement->getDomain());
724   isl_space_free(Space);
725 }
726 
727 void MemoryAccess::realignParams() {
728   isl_space *ParamSpace = Statement->getParent()->getParamSpace();
729   AccessRelation = isl_map_align_params(AccessRelation, ParamSpace);
730 }
731 
732 const std::string MemoryAccess::getReductionOperatorStr() const {
733   return MemoryAccess::getReductionOperatorStr(getReductionType());
734 }
735 
736 __isl_give isl_id *MemoryAccess::getId() const { return isl_id_copy(Id); }
737 
738 raw_ostream &polly::operator<<(raw_ostream &OS,
739                                MemoryAccess::ReductionType RT) {
740   if (RT == MemoryAccess::RT_NONE)
741     OS << "NONE";
742   else
743     OS << MemoryAccess::getReductionOperatorStr(RT);
744   return OS;
745 }
746 
747 void MemoryAccess::print(raw_ostream &OS) const {
748   switch (AccType) {
749   case READ:
750     OS.indent(12) << "ReadAccess :=\t";
751     break;
752   case MUST_WRITE:
753     OS.indent(12) << "MustWriteAccess :=\t";
754     break;
755   case MAY_WRITE:
756     OS.indent(12) << "MayWriteAccess :=\t";
757     break;
758   }
759   OS << "[Reduction Type: " << getReductionType() << "] ";
760   OS << "[Scalar: " << isScalar() << "]\n";
761   OS.indent(16) << getOriginalAccessRelationStr() << ";\n";
762 }
763 
764 void MemoryAccess::dump() const { print(errs()); }
765 
766 // Create a map in the size of the provided set domain, that maps from the
767 // one element of the provided set domain to another element of the provided
768 // set domain.
769 // The mapping is limited to all points that are equal in all but the last
770 // dimension and for which the last dimension of the input is strict smaller
771 // than the last dimension of the output.
772 //
773 //   getEqualAndLarger(set[i0, i1, ..., iX]):
774 //
775 //   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
776 //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
777 //
778 static isl_map *getEqualAndLarger(isl_space *setDomain) {
779   isl_space *Space = isl_space_map_from_set(setDomain);
780   isl_map *Map = isl_map_universe(Space);
781   unsigned lastDimension = isl_map_dim(Map, isl_dim_in) - 1;
782 
783   // Set all but the last dimension to be equal for the input and output
784   //
785   //   input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
786   //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
787   for (unsigned i = 0; i < lastDimension; ++i)
788     Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
789 
790   // Set the last dimension of the input to be strict smaller than the
791   // last dimension of the output.
792   //
793   //   input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
794   Map = isl_map_order_lt(Map, isl_dim_in, lastDimension, isl_dim_out,
795                          lastDimension);
796   return Map;
797 }
798 
799 __isl_give isl_set *
800 MemoryAccess::getStride(__isl_take const isl_map *Schedule) const {
801   isl_map *S = const_cast<isl_map *>(Schedule);
802   isl_map *AccessRelation = getAccessRelation();
803   isl_space *Space = isl_space_range(isl_map_get_space(S));
804   isl_map *NextScatt = getEqualAndLarger(Space);
805 
806   S = isl_map_reverse(S);
807   NextScatt = isl_map_lexmin(NextScatt);
808 
809   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(S));
810   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(AccessRelation));
811   NextScatt = isl_map_apply_domain(NextScatt, S);
812   NextScatt = isl_map_apply_domain(NextScatt, AccessRelation);
813 
814   isl_set *Deltas = isl_map_deltas(NextScatt);
815   return Deltas;
816 }
817 
818 bool MemoryAccess::isStrideX(__isl_take const isl_map *Schedule,
819                              int StrideWidth) const {
820   isl_set *Stride, *StrideX;
821   bool IsStrideX;
822 
823   Stride = getStride(Schedule);
824   StrideX = isl_set_universe(isl_set_get_space(Stride));
825   StrideX = isl_set_fix_si(StrideX, isl_dim_set, 0, StrideWidth);
826   IsStrideX = isl_set_is_equal(Stride, StrideX);
827 
828   isl_set_free(StrideX);
829   isl_set_free(Stride);
830 
831   return IsStrideX;
832 }
833 
834 bool MemoryAccess::isStrideZero(const isl_map *Schedule) const {
835   return isStrideX(Schedule, 0);
836 }
837 
838 bool MemoryAccess::isScalar() const {
839   return isl_map_n_out(AccessRelation) == 0;
840 }
841 
842 bool MemoryAccess::isStrideOne(const isl_map *Schedule) const {
843   return isStrideX(Schedule, 1);
844 }
845 
846 void MemoryAccess::setNewAccessRelation(isl_map *newAccess) {
847   isl_map_free(newAccessRelation);
848   newAccessRelation = newAccess;
849 }
850 
851 //===----------------------------------------------------------------------===//
852 
853 isl_map *ScopStmt::getSchedule() const {
854   isl_set *Domain = getDomain();
855   if (isl_set_is_empty(Domain)) {
856     isl_set_free(Domain);
857     return isl_map_from_aff(
858         isl_aff_zero_on_domain(isl_local_space_from_space(getDomainSpace())));
859   }
860   auto *Schedule = getParent()->getSchedule();
861   Schedule = isl_union_map_intersect_domain(
862       Schedule, isl_union_set_from_set(isl_set_copy(Domain)));
863   if (isl_union_map_is_empty(Schedule)) {
864     isl_set_free(Domain);
865     isl_union_map_free(Schedule);
866     return isl_map_from_aff(
867         isl_aff_zero_on_domain(isl_local_space_from_space(getDomainSpace())));
868   }
869   auto *M = isl_map_from_union_map(Schedule);
870   M = isl_map_coalesce(M);
871   M = isl_map_gist_domain(M, Domain);
872   M = isl_map_coalesce(M);
873   return M;
874 }
875 
876 void ScopStmt::restrictDomain(__isl_take isl_set *NewDomain) {
877   assert(isl_set_is_subset(NewDomain, Domain) &&
878          "New domain is not a subset of old domain!");
879   isl_set_free(Domain);
880   Domain = NewDomain;
881 }
882 
883 void ScopStmt::buildAccesses(TempScop &tempScop, BasicBlock *Block,
884                              bool isApproximated) {
885   AccFuncSetType *AFS = tempScop.getAccessFunctions(Block);
886   if (!AFS)
887     return;
888 
889   for (auto &AccessPair : *AFS) {
890     IRAccess &Access = AccessPair.first;
891     Instruction *AccessInst = AccessPair.second;
892 
893     Type *ElementType = getAccessInstType(AccessInst);
894     const ScopArrayInfo *SAI = getParent()->getOrCreateScopArrayInfo(
895         Access.getBase(), ElementType, Access.Sizes, Access.isPHI());
896 
897     if (isApproximated && Access.isWrite())
898       Access.setMayWrite();
899 
900     MemoryAccessList *&MAL = InstructionToAccess[AccessInst];
901     if (!MAL)
902       MAL = new MemoryAccessList();
903     MAL->emplace_front(Access, AccessInst, this, SAI, MemAccs.size());
904     MemAccs.push_back(&MAL->front());
905   }
906 }
907 
908 void ScopStmt::realignParams() {
909   for (MemoryAccess *MA : *this)
910     MA->realignParams();
911 
912   Domain = isl_set_align_params(Domain, Parent.getParamSpace());
913 }
914 
915 __isl_give isl_set *ScopStmt::buildConditionSet(const Comparison &Comp) {
916   isl_pw_aff *L = SCEVAffinator::getPwAff(this, Comp.getLHS());
917   isl_pw_aff *R = SCEVAffinator::getPwAff(this, Comp.getRHS());
918 
919   switch (Comp.getPred()) {
920   case ICmpInst::ICMP_EQ:
921     return isl_pw_aff_eq_set(L, R);
922   case ICmpInst::ICMP_NE:
923     return isl_pw_aff_ne_set(L, R);
924   case ICmpInst::ICMP_SLT:
925     return isl_pw_aff_lt_set(L, R);
926   case ICmpInst::ICMP_SLE:
927     return isl_pw_aff_le_set(L, R);
928   case ICmpInst::ICMP_SGT:
929     return isl_pw_aff_gt_set(L, R);
930   case ICmpInst::ICMP_SGE:
931     return isl_pw_aff_ge_set(L, R);
932   case ICmpInst::ICMP_ULT:
933     return isl_pw_aff_lt_set(L, R);
934   case ICmpInst::ICMP_UGT:
935     return isl_pw_aff_gt_set(L, R);
936   case ICmpInst::ICMP_ULE:
937     return isl_pw_aff_le_set(L, R);
938   case ICmpInst::ICMP_UGE:
939     return isl_pw_aff_ge_set(L, R);
940   default:
941     llvm_unreachable("Non integer predicate not supported");
942   }
943 }
944 
945 __isl_give isl_set *ScopStmt::addLoopBoundsToDomain(__isl_take isl_set *Domain,
946                                                     TempScop &tempScop) {
947   isl_space *Space;
948   isl_local_space *LocalSpace;
949 
950   Space = isl_set_get_space(Domain);
951   LocalSpace = isl_local_space_from_space(Space);
952 
953   ScalarEvolution *SE = getParent()->getSE();
954   for (int i = 0, e = getNumIterators(); i != e; ++i) {
955     isl_aff *Zero = isl_aff_zero_on_domain(isl_local_space_copy(LocalSpace));
956     isl_pw_aff *IV =
957         isl_pw_aff_from_aff(isl_aff_set_coefficient_si(Zero, isl_dim_in, i, 1));
958 
959     // 0 <= IV.
960     isl_set *LowerBound = isl_pw_aff_nonneg_set(isl_pw_aff_copy(IV));
961     Domain = isl_set_intersect(Domain, LowerBound);
962 
963     // IV <= LatchExecutions.
964     const Loop *L = getLoopForDimension(i);
965     const SCEV *LatchExecutions = SE->getBackedgeTakenCount(L);
966     isl_pw_aff *UpperBound = SCEVAffinator::getPwAff(this, LatchExecutions);
967     isl_set *UpperBoundSet = isl_pw_aff_le_set(IV, UpperBound);
968     Domain = isl_set_intersect(Domain, UpperBoundSet);
969   }
970 
971   isl_local_space_free(LocalSpace);
972   return Domain;
973 }
974 
975 __isl_give isl_set *ScopStmt::addConditionsToDomain(__isl_take isl_set *Domain,
976                                                     TempScop &tempScop,
977                                                     const Region &CurRegion) {
978   const Region *TopRegion = tempScop.getMaxRegion().getParent(),
979                *CurrentRegion = &CurRegion;
980   const BasicBlock *BranchingBB = BB ? BB : R->getEntry();
981 
982   do {
983     if (BranchingBB != CurrentRegion->getEntry()) {
984       if (const BBCond *Condition = tempScop.getBBCond(BranchingBB))
985         for (const auto &C : *Condition) {
986           isl_set *ConditionSet = buildConditionSet(C);
987           Domain = isl_set_intersect(Domain, ConditionSet);
988         }
989     }
990     BranchingBB = CurrentRegion->getEntry();
991     CurrentRegion = CurrentRegion->getParent();
992   } while (TopRegion != CurrentRegion);
993 
994   return Domain;
995 }
996 
997 __isl_give isl_set *ScopStmt::buildDomain(TempScop &tempScop,
998                                           const Region &CurRegion) {
999   isl_space *Space;
1000   isl_set *Domain;
1001   isl_id *Id;
1002 
1003   Space = isl_space_set_alloc(getIslCtx(), 0, getNumIterators());
1004 
1005   Id = isl_id_alloc(getIslCtx(), getBaseName(), this);
1006 
1007   Domain = isl_set_universe(Space);
1008   Domain = addLoopBoundsToDomain(Domain, tempScop);
1009   Domain = addConditionsToDomain(Domain, tempScop, CurRegion);
1010   Domain = isl_set_set_tuple_id(Domain, Id);
1011 
1012   return Domain;
1013 }
1014 
1015 void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP) {
1016   int Dimension = 0;
1017   isl_ctx *Ctx = Parent.getIslCtx();
1018   isl_local_space *LSpace = isl_local_space_from_space(getDomainSpace());
1019   Type *Ty = GEP->getPointerOperandType();
1020   ScalarEvolution &SE = *Parent.getSE();
1021 
1022   if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
1023     Dimension = 1;
1024     Ty = PtrTy->getElementType();
1025   }
1026 
1027   while (auto ArrayTy = dyn_cast<ArrayType>(Ty)) {
1028     unsigned int Operand = 1 + Dimension;
1029 
1030     if (GEP->getNumOperands() <= Operand)
1031       break;
1032 
1033     const SCEV *Expr = SE.getSCEV(GEP->getOperand(Operand));
1034 
1035     if (isAffineExpr(&Parent.getRegion(), Expr, SE)) {
1036       isl_pw_aff *AccessOffset = SCEVAffinator::getPwAff(this, Expr);
1037       AccessOffset =
1038           isl_pw_aff_set_tuple_id(AccessOffset, isl_dim_in, getDomainId());
1039 
1040       isl_pw_aff *DimSize = isl_pw_aff_from_aff(isl_aff_val_on_domain(
1041           isl_local_space_copy(LSpace),
1042           isl_val_int_from_si(Ctx, ArrayTy->getNumElements())));
1043 
1044       isl_set *OutOfBound = isl_pw_aff_ge_set(AccessOffset, DimSize);
1045       OutOfBound = isl_set_intersect(getDomain(), OutOfBound);
1046       OutOfBound = isl_set_params(OutOfBound);
1047       isl_set *InBound = isl_set_complement(OutOfBound);
1048       isl_set *Executed = isl_set_params(getDomain());
1049 
1050       // A => B == !A or B
1051       isl_set *InBoundIfExecuted =
1052           isl_set_union(isl_set_complement(Executed), InBound);
1053 
1054       Parent.addAssumption(InBoundIfExecuted);
1055     }
1056 
1057     Dimension += 1;
1058     Ty = ArrayTy->getElementType();
1059   }
1060 
1061   isl_local_space_free(LSpace);
1062 }
1063 
1064 void ScopStmt::deriveAssumptions(BasicBlock *Block) {
1065   for (Instruction &Inst : *Block)
1066     if (auto *GEP = dyn_cast<GetElementPtrInst>(&Inst))
1067       deriveAssumptionsFromGEP(GEP);
1068 }
1069 
1070 ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
1071                    Region &R, SmallVectorImpl<Loop *> &Nest)
1072     : Parent(parent), BB(nullptr), R(&R), Build(nullptr),
1073       NestLoops(Nest.size()) {
1074   // Setup the induction variables.
1075   for (unsigned i = 0, e = Nest.size(); i < e; ++i)
1076     NestLoops[i] = Nest[i];
1077 
1078   BaseName = getIslCompatibleName("Stmt_", R.getNameStr(), "");
1079 
1080   Domain = buildDomain(tempScop, CurRegion);
1081 
1082   BasicBlock *EntryBB = R.getEntry();
1083   for (BasicBlock *Block : R.blocks()) {
1084     buildAccesses(tempScop, Block, Block != EntryBB);
1085     deriveAssumptions(Block);
1086   }
1087   checkForReductions();
1088 }
1089 
1090 ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
1091                    BasicBlock &bb, SmallVectorImpl<Loop *> &Nest)
1092     : Parent(parent), BB(&bb), R(nullptr), Build(nullptr),
1093       NestLoops(Nest.size()) {
1094   // Setup the induction variables.
1095   for (unsigned i = 0, e = Nest.size(); i < e; ++i)
1096     NestLoops[i] = Nest[i];
1097 
1098   BaseName = getIslCompatibleName("Stmt_", &bb, "");
1099 
1100   Domain = buildDomain(tempScop, CurRegion);
1101   buildAccesses(tempScop, BB);
1102   deriveAssumptions(BB);
1103   checkForReductions();
1104 }
1105 
1106 /// @brief Collect loads which might form a reduction chain with @p StoreMA
1107 ///
1108 /// Check if the stored value for @p StoreMA is a binary operator with one or
1109 /// two loads as operands. If the binary operand is commutative & associative,
1110 /// used only once (by @p StoreMA) and its load operands are also used only
1111 /// once, we have found a possible reduction chain. It starts at an operand
1112 /// load and includes the binary operator and @p StoreMA.
1113 ///
1114 /// Note: We allow only one use to ensure the load and binary operator cannot
1115 ///       escape this block or into any other store except @p StoreMA.
1116 void ScopStmt::collectCandiateReductionLoads(
1117     MemoryAccess *StoreMA, SmallVectorImpl<MemoryAccess *> &Loads) {
1118   auto *Store = dyn_cast<StoreInst>(StoreMA->getAccessInstruction());
1119   if (!Store)
1120     return;
1121 
1122   // Skip if there is not one binary operator between the load and the store
1123   auto *BinOp = dyn_cast<BinaryOperator>(Store->getValueOperand());
1124   if (!BinOp)
1125     return;
1126 
1127   // Skip if the binary operators has multiple uses
1128   if (BinOp->getNumUses() != 1)
1129     return;
1130 
1131   // Skip if the opcode of the binary operator is not commutative/associative
1132   if (!BinOp->isCommutative() || !BinOp->isAssociative())
1133     return;
1134 
1135   // Skip if the binary operator is outside the current SCoP
1136   if (BinOp->getParent() != Store->getParent())
1137     return;
1138 
1139   // Skip if it is a multiplicative reduction and we disabled them
1140   if (DisableMultiplicativeReductions &&
1141       (BinOp->getOpcode() == Instruction::Mul ||
1142        BinOp->getOpcode() == Instruction::FMul))
1143     return;
1144 
1145   // Check the binary operator operands for a candidate load
1146   auto *PossibleLoad0 = dyn_cast<LoadInst>(BinOp->getOperand(0));
1147   auto *PossibleLoad1 = dyn_cast<LoadInst>(BinOp->getOperand(1));
1148   if (!PossibleLoad0 && !PossibleLoad1)
1149     return;
1150 
1151   // A load is only a candidate if it cannot escape (thus has only this use)
1152   if (PossibleLoad0 && PossibleLoad0->getNumUses() == 1)
1153     if (PossibleLoad0->getParent() == Store->getParent())
1154       Loads.push_back(lookupAccessFor(PossibleLoad0));
1155   if (PossibleLoad1 && PossibleLoad1->getNumUses() == 1)
1156     if (PossibleLoad1->getParent() == Store->getParent())
1157       Loads.push_back(lookupAccessFor(PossibleLoad1));
1158 }
1159 
1160 /// @brief Check for reductions in this ScopStmt
1161 ///
1162 /// Iterate over all store memory accesses and check for valid binary reduction
1163 /// like chains. For all candidates we check if they have the same base address
1164 /// and there are no other accesses which overlap with them. The base address
1165 /// check rules out impossible reductions candidates early. The overlap check,
1166 /// together with the "only one user" check in collectCandiateReductionLoads,
1167 /// guarantees that none of the intermediate results will escape during
1168 /// execution of the loop nest. We basically check here that no other memory
1169 /// access can access the same memory as the potential reduction.
1170 void ScopStmt::checkForReductions() {
1171   SmallVector<MemoryAccess *, 2> Loads;
1172   SmallVector<std::pair<MemoryAccess *, MemoryAccess *>, 4> Candidates;
1173 
1174   // First collect candidate load-store reduction chains by iterating over all
1175   // stores and collecting possible reduction loads.
1176   for (MemoryAccess *StoreMA : MemAccs) {
1177     if (StoreMA->isRead())
1178       continue;
1179 
1180     Loads.clear();
1181     collectCandiateReductionLoads(StoreMA, Loads);
1182     for (MemoryAccess *LoadMA : Loads)
1183       Candidates.push_back(std::make_pair(LoadMA, StoreMA));
1184   }
1185 
1186   // Then check each possible candidate pair.
1187   for (const auto &CandidatePair : Candidates) {
1188     bool Valid = true;
1189     isl_map *LoadAccs = CandidatePair.first->getAccessRelation();
1190     isl_map *StoreAccs = CandidatePair.second->getAccessRelation();
1191 
1192     // Skip those with obviously unequal base addresses.
1193     if (!isl_map_has_equal_space(LoadAccs, StoreAccs)) {
1194       isl_map_free(LoadAccs);
1195       isl_map_free(StoreAccs);
1196       continue;
1197     }
1198 
1199     // And check if the remaining for overlap with other memory accesses.
1200     isl_map *AllAccsRel = isl_map_union(LoadAccs, StoreAccs);
1201     AllAccsRel = isl_map_intersect_domain(AllAccsRel, getDomain());
1202     isl_set *AllAccs = isl_map_range(AllAccsRel);
1203 
1204     for (MemoryAccess *MA : MemAccs) {
1205       if (MA == CandidatePair.first || MA == CandidatePair.second)
1206         continue;
1207 
1208       isl_map *AccRel =
1209           isl_map_intersect_domain(MA->getAccessRelation(), getDomain());
1210       isl_set *Accs = isl_map_range(AccRel);
1211 
1212       if (isl_set_has_equal_space(AllAccs, Accs) || isl_set_free(Accs)) {
1213         isl_set *OverlapAccs = isl_set_intersect(Accs, isl_set_copy(AllAccs));
1214         Valid = Valid && isl_set_is_empty(OverlapAccs);
1215         isl_set_free(OverlapAccs);
1216       }
1217     }
1218 
1219     isl_set_free(AllAccs);
1220     if (!Valid)
1221       continue;
1222 
1223     const LoadInst *Load =
1224         dyn_cast<const LoadInst>(CandidatePair.first->getAccessInstruction());
1225     MemoryAccess::ReductionType RT =
1226         getReductionType(dyn_cast<BinaryOperator>(Load->user_back()), Load);
1227 
1228     // If no overlapping access was found we mark the load and store as
1229     // reduction like.
1230     CandidatePair.first->markAsReductionLike(RT);
1231     CandidatePair.second->markAsReductionLike(RT);
1232   }
1233 }
1234 
1235 std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
1236 
1237 std::string ScopStmt::getScheduleStr() const {
1238   auto *S = getSchedule();
1239   auto Str = stringFromIslObj(S);
1240   isl_map_free(S);
1241   return Str;
1242 }
1243 
1244 unsigned ScopStmt::getNumParams() const { return Parent.getNumParams(); }
1245 
1246 unsigned ScopStmt::getNumIterators() const { return NestLoops.size(); }
1247 
1248 const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
1249 
1250 const Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
1251   return NestLoops[Dimension];
1252 }
1253 
1254 isl_ctx *ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
1255 
1256 __isl_give isl_set *ScopStmt::getDomain() const { return isl_set_copy(Domain); }
1257 
1258 __isl_give isl_space *ScopStmt::getDomainSpace() const {
1259   return isl_set_get_space(Domain);
1260 }
1261 
1262 __isl_give isl_id *ScopStmt::getDomainId() const {
1263   return isl_set_get_tuple_id(Domain);
1264 }
1265 
1266 ScopStmt::~ScopStmt() {
1267   DeleteContainerSeconds(InstructionToAccess);
1268   isl_set_free(Domain);
1269 }
1270 
1271 void ScopStmt::print(raw_ostream &OS) const {
1272   OS << "\t" << getBaseName() << "\n";
1273   OS.indent(12) << "Domain :=\n";
1274 
1275   if (Domain) {
1276     OS.indent(16) << getDomainStr() << ";\n";
1277   } else
1278     OS.indent(16) << "n/a\n";
1279 
1280   OS.indent(12) << "Schedule :=\n";
1281 
1282   if (Domain) {
1283     OS.indent(16) << getScheduleStr() << ";\n";
1284   } else
1285     OS.indent(16) << "n/a\n";
1286 
1287   for (MemoryAccess *Access : MemAccs)
1288     Access->print(OS);
1289 }
1290 
1291 void ScopStmt::dump() const { print(dbgs()); }
1292 
1293 //===----------------------------------------------------------------------===//
1294 /// Scop class implement
1295 
1296 void Scop::setContext(__isl_take isl_set *NewContext) {
1297   NewContext = isl_set_align_params(NewContext, isl_set_get_space(Context));
1298   isl_set_free(Context);
1299   Context = NewContext;
1300 }
1301 
1302 void Scop::addParams(std::vector<const SCEV *> NewParameters) {
1303   for (const SCEV *Parameter : NewParameters) {
1304     Parameter = extractConstantFactor(Parameter, *SE).second;
1305     if (ParameterIds.find(Parameter) != ParameterIds.end())
1306       continue;
1307 
1308     int dimension = Parameters.size();
1309 
1310     Parameters.push_back(Parameter);
1311     ParameterIds[Parameter] = dimension;
1312   }
1313 }
1314 
1315 __isl_give isl_id *Scop::getIdForParam(const SCEV *Parameter) const {
1316   ParamIdType::const_iterator IdIter = ParameterIds.find(Parameter);
1317 
1318   if (IdIter == ParameterIds.end())
1319     return nullptr;
1320 
1321   std::string ParameterName;
1322 
1323   if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
1324     Value *Val = ValueParameter->getValue();
1325     ParameterName = Val->getName();
1326   }
1327 
1328   if (ParameterName == "" || ParameterName.substr(0, 2) == "p_")
1329     ParameterName = "p_" + utostr_32(IdIter->second);
1330 
1331   return isl_id_alloc(getIslCtx(), ParameterName.c_str(),
1332                       const_cast<void *>((const void *)Parameter));
1333 }
1334 
1335 void Scop::buildContext() {
1336   isl_space *Space = isl_space_params_alloc(IslCtx, 0);
1337   Context = isl_set_universe(isl_space_copy(Space));
1338   AssumedContext = isl_set_universe(Space);
1339 }
1340 
1341 void Scop::addParameterBounds() {
1342   for (const auto &ParamID : ParameterIds) {
1343     int dim = ParamID.second;
1344 
1345     ConstantRange SRange = SE->getSignedRange(ParamID.first);
1346 
1347     Context = addRangeBoundsToSet(Context, SRange, dim, isl_dim_param);
1348   }
1349 }
1350 
1351 void Scop::realignParams() {
1352   // Add all parameters into a common model.
1353   isl_space *Space = isl_space_params_alloc(IslCtx, ParameterIds.size());
1354 
1355   for (const auto &ParamID : ParameterIds) {
1356     const SCEV *Parameter = ParamID.first;
1357     isl_id *id = getIdForParam(Parameter);
1358     Space = isl_space_set_dim_id(Space, isl_dim_param, ParamID.second, id);
1359   }
1360 
1361   // Align the parameters of all data structures to the model.
1362   Context = isl_set_align_params(Context, Space);
1363 
1364   for (ScopStmt &Stmt : *this)
1365     Stmt.realignParams();
1366 }
1367 
1368 void Scop::simplifyAssumedContext() {
1369   // The parameter constraints of the iteration domains give us a set of
1370   // constraints that need to hold for all cases where at least a single
1371   // statement iteration is executed in the whole scop. We now simplify the
1372   // assumed context under the assumption that such constraints hold and at
1373   // least a single statement iteration is executed. For cases where no
1374   // statement instances are executed, the assumptions we have taken about
1375   // the executed code do not matter and can be changed.
1376   //
1377   // WARNING: This only holds if the assumptions we have taken do not reduce
1378   //          the set of statement instances that are executed. Otherwise we
1379   //          may run into a case where the iteration domains suggest that
1380   //          for a certain set of parameter constraints no code is executed,
1381   //          but in the original program some computation would have been
1382   //          performed. In such a case, modifying the run-time conditions and
1383   //          possibly influencing the run-time check may cause certain scops
1384   //          to not be executed.
1385   //
1386   // Example:
1387   //
1388   //   When delinearizing the following code:
1389   //
1390   //     for (long i = 0; i < 100; i++)
1391   //       for (long j = 0; j < m; j++)
1392   //         A[i+p][j] = 1.0;
1393   //
1394   //   we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
1395   //   otherwise we would access out of bound data. Now, knowing that code is
1396   //   only executed for the case m >= 0, it is sufficient to assume p >= 0.
1397   AssumedContext =
1398       isl_set_gist_params(AssumedContext, isl_union_set_params(getDomains()));
1399   AssumedContext = isl_set_gist_params(AssumedContext, getContext());
1400 }
1401 
1402 /// @brief Add the minimal/maximal access in @p Set to @p User.
1403 static isl_stat buildMinMaxAccess(__isl_take isl_set *Set, void *User) {
1404   Scop::MinMaxVectorTy *MinMaxAccesses = (Scop::MinMaxVectorTy *)User;
1405   isl_pw_multi_aff *MinPMA, *MaxPMA;
1406   isl_pw_aff *LastDimAff;
1407   isl_aff *OneAff;
1408   unsigned Pos;
1409 
1410   // Restrict the number of parameters involved in the access as the lexmin/
1411   // lexmax computation will take too long if this number is high.
1412   //
1413   // Experiments with a simple test case using an i7 4800MQ:
1414   //
1415   //  #Parameters involved | Time (in sec)
1416   //            6          |     0.01
1417   //            7          |     0.04
1418   //            8          |     0.12
1419   //            9          |     0.40
1420   //           10          |     1.54
1421   //           11          |     6.78
1422   //           12          |    30.38
1423   //
1424   if (isl_set_n_param(Set) > RunTimeChecksMaxParameters) {
1425     unsigned InvolvedParams = 0;
1426     for (unsigned u = 0, e = isl_set_n_param(Set); u < e; u++)
1427       if (isl_set_involves_dims(Set, isl_dim_param, u, 1))
1428         InvolvedParams++;
1429 
1430     if (InvolvedParams > RunTimeChecksMaxParameters) {
1431       isl_set_free(Set);
1432       return isl_stat_error;
1433     }
1434   }
1435 
1436   Set = isl_set_remove_divs(Set);
1437 
1438   MinPMA = isl_set_lexmin_pw_multi_aff(isl_set_copy(Set));
1439   MaxPMA = isl_set_lexmax_pw_multi_aff(isl_set_copy(Set));
1440 
1441   MinPMA = isl_pw_multi_aff_coalesce(MinPMA);
1442   MaxPMA = isl_pw_multi_aff_coalesce(MaxPMA);
1443 
1444   // Adjust the last dimension of the maximal access by one as we want to
1445   // enclose the accessed memory region by MinPMA and MaxPMA. The pointer
1446   // we test during code generation might now point after the end of the
1447   // allocated array but we will never dereference it anyway.
1448   assert(isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) &&
1449          "Assumed at least one output dimension");
1450   Pos = isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) - 1;
1451   LastDimAff = isl_pw_multi_aff_get_pw_aff(MaxPMA, Pos);
1452   OneAff = isl_aff_zero_on_domain(
1453       isl_local_space_from_space(isl_pw_aff_get_domain_space(LastDimAff)));
1454   OneAff = isl_aff_add_constant_si(OneAff, 1);
1455   LastDimAff = isl_pw_aff_add(LastDimAff, isl_pw_aff_from_aff(OneAff));
1456   MaxPMA = isl_pw_multi_aff_set_pw_aff(MaxPMA, Pos, LastDimAff);
1457 
1458   MinMaxAccesses->push_back(std::make_pair(MinPMA, MaxPMA));
1459 
1460   isl_set_free(Set);
1461   return isl_stat_ok;
1462 }
1463 
1464 static __isl_give isl_set *getAccessDomain(MemoryAccess *MA) {
1465   isl_set *Domain = MA->getStatement()->getDomain();
1466   Domain = isl_set_project_out(Domain, isl_dim_set, 0, isl_set_n_dim(Domain));
1467   return isl_set_reset_tuple_id(Domain);
1468 }
1469 
1470 /// @brief Wrapper function to calculate minimal/maximal accesses to each array.
1471 static bool calculateMinMaxAccess(__isl_take isl_union_map *Accesses,
1472                                   __isl_take isl_union_set *Domains,
1473                                   __isl_take isl_set *AssumedContext,
1474                                   Scop::MinMaxVectorTy &MinMaxAccesses) {
1475 
1476   Accesses = isl_union_map_intersect_domain(Accesses, Domains);
1477   isl_union_set *Locations = isl_union_map_range(Accesses);
1478   Locations = isl_union_set_intersect_params(Locations, AssumedContext);
1479   Locations = isl_union_set_coalesce(Locations);
1480   Locations = isl_union_set_detect_equalities(Locations);
1481   bool Valid = (0 == isl_union_set_foreach_set(Locations, buildMinMaxAccess,
1482                                                &MinMaxAccesses));
1483   isl_union_set_free(Locations);
1484   return Valid;
1485 }
1486 
1487 bool Scop::buildAliasGroups(AliasAnalysis &AA) {
1488   // To create sound alias checks we perform the following steps:
1489   //   o) Use the alias analysis and an alias set tracker to build alias sets
1490   //      for all memory accesses inside the SCoP.
1491   //   o) For each alias set we then map the aliasing pointers back to the
1492   //      memory accesses we know, thus obtain groups of memory accesses which
1493   //      might alias.
1494   //   o) We divide each group based on the domains of the minimal/maximal
1495   //      accesses. That means two minimal/maximal accesses are only in a group
1496   //      if their access domains intersect, otherwise they are in different
1497   //      ones.
1498   //   o) We partition each group into read only and non read only accesses.
1499   //   o) For each group with more than one base pointer we then compute minimal
1500   //      and maximal accesses to each array of a group in read only and non
1501   //      read only partitions separately.
1502   using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
1503 
1504   AliasSetTracker AST(AA);
1505 
1506   DenseMap<Value *, MemoryAccess *> PtrToAcc;
1507   DenseSet<Value *> HasWriteAccess;
1508   for (ScopStmt &Stmt : *this) {
1509 
1510     // Skip statements with an empty domain as they will never be executed.
1511     isl_set *StmtDomain = Stmt.getDomain();
1512     bool StmtDomainEmpty = isl_set_is_empty(StmtDomain);
1513     isl_set_free(StmtDomain);
1514     if (StmtDomainEmpty)
1515       continue;
1516 
1517     for (MemoryAccess *MA : Stmt) {
1518       if (MA->isScalar())
1519         continue;
1520       if (!MA->isRead())
1521         HasWriteAccess.insert(MA->getBaseAddr());
1522       Instruction *Acc = MA->getAccessInstruction();
1523       PtrToAcc[getPointerOperand(*Acc)] = MA;
1524       AST.add(Acc);
1525     }
1526   }
1527 
1528   SmallVector<AliasGroupTy, 4> AliasGroups;
1529   for (AliasSet &AS : AST) {
1530     if (AS.isMustAlias() || AS.isForwardingAliasSet())
1531       continue;
1532     AliasGroupTy AG;
1533     for (auto PR : AS)
1534       AG.push_back(PtrToAcc[PR.getValue()]);
1535     assert(AG.size() > 1 &&
1536            "Alias groups should contain at least two accesses");
1537     AliasGroups.push_back(std::move(AG));
1538   }
1539 
1540   // Split the alias groups based on their domain.
1541   for (unsigned u = 0; u < AliasGroups.size(); u++) {
1542     AliasGroupTy NewAG;
1543     AliasGroupTy &AG = AliasGroups[u];
1544     AliasGroupTy::iterator AGI = AG.begin();
1545     isl_set *AGDomain = getAccessDomain(*AGI);
1546     while (AGI != AG.end()) {
1547       MemoryAccess *MA = *AGI;
1548       isl_set *MADomain = getAccessDomain(MA);
1549       if (isl_set_is_disjoint(AGDomain, MADomain)) {
1550         NewAG.push_back(MA);
1551         AGI = AG.erase(AGI);
1552         isl_set_free(MADomain);
1553       } else {
1554         AGDomain = isl_set_union(AGDomain, MADomain);
1555         AGI++;
1556       }
1557     }
1558     if (NewAG.size() > 1)
1559       AliasGroups.push_back(std::move(NewAG));
1560     isl_set_free(AGDomain);
1561   }
1562 
1563   MapVector<const Value *, SmallPtrSet<MemoryAccess *, 8>> ReadOnlyPairs;
1564   SmallPtrSet<const Value *, 4> NonReadOnlyBaseValues;
1565   for (AliasGroupTy &AG : AliasGroups) {
1566     NonReadOnlyBaseValues.clear();
1567     ReadOnlyPairs.clear();
1568 
1569     if (AG.size() < 2) {
1570       AG.clear();
1571       continue;
1572     }
1573 
1574     for (auto II = AG.begin(); II != AG.end();) {
1575       Value *BaseAddr = (*II)->getBaseAddr();
1576       if (HasWriteAccess.count(BaseAddr)) {
1577         NonReadOnlyBaseValues.insert(BaseAddr);
1578         II++;
1579       } else {
1580         ReadOnlyPairs[BaseAddr].insert(*II);
1581         II = AG.erase(II);
1582       }
1583     }
1584 
1585     // If we don't have read only pointers check if there are at least two
1586     // non read only pointers, otherwise clear the alias group.
1587     if (ReadOnlyPairs.empty() && NonReadOnlyBaseValues.size() <= 1) {
1588       AG.clear();
1589       continue;
1590     }
1591 
1592     // If we don't have non read only pointers clear the alias group.
1593     if (NonReadOnlyBaseValues.empty()) {
1594       AG.clear();
1595       continue;
1596     }
1597 
1598     // Calculate minimal and maximal accesses for non read only accesses.
1599     MinMaxAliasGroups.emplace_back();
1600     MinMaxVectorPairTy &pair = MinMaxAliasGroups.back();
1601     MinMaxVectorTy &MinMaxAccessesNonReadOnly = pair.first;
1602     MinMaxVectorTy &MinMaxAccessesReadOnly = pair.second;
1603     MinMaxAccessesNonReadOnly.reserve(AG.size());
1604 
1605     isl_union_map *Accesses = isl_union_map_empty(getParamSpace());
1606 
1607     // AG contains only non read only accesses.
1608     for (MemoryAccess *MA : AG)
1609       Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation());
1610 
1611     bool Valid = calculateMinMaxAccess(
1612         Accesses, getDomains(), getAssumedContext(), MinMaxAccessesNonReadOnly);
1613 
1614     // Bail out if the number of values we need to compare is too large.
1615     // This is important as the number of comparisions grows quadratically with
1616     // the number of values we need to compare.
1617     if (!Valid || (MinMaxAccessesNonReadOnly.size() + !ReadOnlyPairs.empty() >
1618                    RunTimeChecksMaxArraysPerGroup))
1619       return false;
1620 
1621     // Calculate minimal and maximal accesses for read only accesses.
1622     MinMaxAccessesReadOnly.reserve(ReadOnlyPairs.size());
1623     Accesses = isl_union_map_empty(getParamSpace());
1624 
1625     for (const auto &ReadOnlyPair : ReadOnlyPairs)
1626       for (MemoryAccess *MA : ReadOnlyPair.second)
1627         Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation());
1628 
1629     Valid = calculateMinMaxAccess(Accesses, getDomains(), getAssumedContext(),
1630                                   MinMaxAccessesReadOnly);
1631 
1632     if (!Valid)
1633       return false;
1634   }
1635 
1636   return true;
1637 }
1638 
1639 static unsigned getMaxLoopDepthInRegion(const Region &R, LoopInfo &LI,
1640                                         ScopDetection &SD) {
1641 
1642   const ScopDetection::BoxedLoopsSetTy *BoxedLoops = SD.getBoxedLoops(&R);
1643 
1644   unsigned MinLD = INT_MAX, MaxLD = 0;
1645   for (BasicBlock *BB : R.blocks()) {
1646     if (Loop *L = LI.getLoopFor(BB)) {
1647       if (!R.contains(L))
1648         continue;
1649       if (BoxedLoops && BoxedLoops->count(L))
1650         continue;
1651       unsigned LD = L->getLoopDepth();
1652       MinLD = std::min(MinLD, LD);
1653       MaxLD = std::max(MaxLD, LD);
1654     }
1655   }
1656 
1657   // Handle the case that there is no loop in the SCoP first.
1658   if (MaxLD == 0)
1659     return 1;
1660 
1661   assert(MinLD >= 1 && "Minimal loop depth should be at least one");
1662   assert(MaxLD >= MinLD &&
1663          "Maximal loop depth was smaller than mininaml loop depth?");
1664   return MaxLD - MinLD + 1;
1665 }
1666 
1667 Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution,
1668            ScopDetection &SD, isl_ctx *Context)
1669     : SE(&ScalarEvolution), R(tempScop.getMaxRegion()), IsOptimized(false),
1670       MaxLoopDepth(getMaxLoopDepthInRegion(tempScop.getMaxRegion(), LI, SD)) {
1671   IslCtx = Context;
1672 
1673   buildContext();
1674 
1675   SmallVector<Loop *, 8> NestLoops;
1676 
1677   // Build the iteration domain, access functions and schedule functions
1678   // traversing the region tree.
1679   Schedule = buildScop(tempScop, getRegion(), NestLoops, LI, SD);
1680   if (!Schedule)
1681     Schedule = isl_schedule_empty(getParamSpace());
1682 
1683   realignParams();
1684   addParameterBounds();
1685   simplifyAssumedContext();
1686 
1687   assert(NestLoops.empty() && "NestLoops not empty at top level!");
1688 }
1689 
1690 Scop::~Scop() {
1691   isl_set_free(Context);
1692   isl_set_free(AssumedContext);
1693   isl_schedule_free(Schedule);
1694 
1695   // Free the alias groups
1696   for (MinMaxVectorPairTy &MinMaxAccessPair : MinMaxAliasGroups) {
1697     for (MinMaxAccessTy &MMA : MinMaxAccessPair.first) {
1698       isl_pw_multi_aff_free(MMA.first);
1699       isl_pw_multi_aff_free(MMA.second);
1700     }
1701     for (MinMaxAccessTy &MMA : MinMaxAccessPair.second) {
1702       isl_pw_multi_aff_free(MMA.first);
1703       isl_pw_multi_aff_free(MMA.second);
1704     }
1705   }
1706 }
1707 
1708 const ScopArrayInfo *
1709 Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType,
1710                                const SmallVector<const SCEV *, 4> &Sizes,
1711                                bool IsPHI) {
1712   auto &SAI = ScopArrayInfoMap[std::make_pair(BasePtr, IsPHI)];
1713   if (!SAI)
1714     SAI.reset(
1715         new ScopArrayInfo(BasePtr, AccessType, getIslCtx(), Sizes, IsPHI));
1716   return SAI.get();
1717 }
1718 
1719 const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, bool IsPHI) {
1720   auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, IsPHI)].get();
1721   assert(SAI && "No ScopArrayInfo available for this base pointer");
1722   return SAI;
1723 }
1724 
1725 std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
1726 std::string Scop::getAssumedContextStr() const {
1727   return stringFromIslObj(AssumedContext);
1728 }
1729 
1730 std::string Scop::getNameStr() const {
1731   std::string ExitName, EntryName;
1732   raw_string_ostream ExitStr(ExitName);
1733   raw_string_ostream EntryStr(EntryName);
1734 
1735   R.getEntry()->printAsOperand(EntryStr, false);
1736   EntryStr.str();
1737 
1738   if (R.getExit()) {
1739     R.getExit()->printAsOperand(ExitStr, false);
1740     ExitStr.str();
1741   } else
1742     ExitName = "FunctionExit";
1743 
1744   return EntryName + "---" + ExitName;
1745 }
1746 
1747 __isl_give isl_set *Scop::getContext() const { return isl_set_copy(Context); }
1748 __isl_give isl_space *Scop::getParamSpace() const {
1749   return isl_set_get_space(Context);
1750 }
1751 
1752 __isl_give isl_set *Scop::getAssumedContext() const {
1753   return isl_set_copy(AssumedContext);
1754 }
1755 
1756 void Scop::addAssumption(__isl_take isl_set *Set) {
1757   AssumedContext = isl_set_intersect(AssumedContext, Set);
1758   AssumedContext = isl_set_coalesce(AssumedContext);
1759 }
1760 
1761 void Scop::printContext(raw_ostream &OS) const {
1762   OS << "Context:\n";
1763 
1764   if (!Context) {
1765     OS.indent(4) << "n/a\n\n";
1766     return;
1767   }
1768 
1769   OS.indent(4) << getContextStr() << "\n";
1770 
1771   OS.indent(4) << "Assumed Context:\n";
1772   if (!AssumedContext) {
1773     OS.indent(4) << "n/a\n\n";
1774     return;
1775   }
1776 
1777   OS.indent(4) << getAssumedContextStr() << "\n";
1778 
1779   for (const SCEV *Parameter : Parameters) {
1780     int Dim = ParameterIds.find(Parameter)->second;
1781     OS.indent(4) << "p" << Dim << ": " << *Parameter << "\n";
1782   }
1783 }
1784 
1785 void Scop::printAliasAssumptions(raw_ostream &OS) const {
1786   int noOfGroups = 0;
1787   for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
1788     if (Pair.second.size() == 0)
1789       noOfGroups += 1;
1790     else
1791       noOfGroups += Pair.second.size();
1792   }
1793 
1794   OS.indent(4) << "Alias Groups (" << noOfGroups << "):\n";
1795   if (MinMaxAliasGroups.empty()) {
1796     OS.indent(8) << "n/a\n";
1797     return;
1798   }
1799 
1800   for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
1801 
1802     // If the group has no read only accesses print the write accesses.
1803     if (Pair.second.empty()) {
1804       OS.indent(8) << "[[";
1805       for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
1806         OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
1807            << ">";
1808       }
1809       OS << " ]]\n";
1810     }
1811 
1812     for (const MinMaxAccessTy &MMAReadOnly : Pair.second) {
1813       OS.indent(8) << "[[";
1814       OS << " <" << MMAReadOnly.first << ", " << MMAReadOnly.second << ">";
1815       for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
1816         OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
1817            << ">";
1818       }
1819       OS << " ]]\n";
1820     }
1821   }
1822 }
1823 
1824 void Scop::printStatements(raw_ostream &OS) const {
1825   OS << "Statements {\n";
1826 
1827   for (const ScopStmt &Stmt : *this)
1828     OS.indent(4) << Stmt;
1829 
1830   OS.indent(4) << "}\n";
1831 }
1832 
1833 void Scop::printArrayInfo(raw_ostream &OS) const {
1834   OS << "Arrays {\n";
1835 
1836   for (auto &Array : arrays())
1837     Array.second->print(OS);
1838 
1839   OS.indent(4) << "}\n";
1840 }
1841 
1842 void Scop::print(raw_ostream &OS) const {
1843   OS.indent(4) << "Function: " << getRegion().getEntry()->getParent()->getName()
1844                << "\n";
1845   OS.indent(4) << "Region: " << getNameStr() << "\n";
1846   OS.indent(4) << "Max Loop Depth:  " << getMaxLoopDepth() << "\n";
1847   printContext(OS.indent(4));
1848   printArrayInfo(OS.indent(4));
1849   printAliasAssumptions(OS);
1850   printStatements(OS.indent(4));
1851 }
1852 
1853 void Scop::dump() const { print(dbgs()); }
1854 
1855 isl_ctx *Scop::getIslCtx() const { return IslCtx; }
1856 
1857 __isl_give isl_union_set *Scop::getDomains() const {
1858   isl_union_set *Domain = isl_union_set_empty(getParamSpace());
1859 
1860   for (const ScopStmt &Stmt : *this)
1861     Domain = isl_union_set_add_set(Domain, Stmt.getDomain());
1862 
1863   return Domain;
1864 }
1865 
1866 __isl_give isl_union_map *Scop::getMustWrites() {
1867   isl_union_map *Write = isl_union_map_empty(getParamSpace());
1868 
1869   for (ScopStmt &Stmt : *this) {
1870     for (MemoryAccess *MA : Stmt) {
1871       if (!MA->isMustWrite())
1872         continue;
1873 
1874       isl_set *Domain = Stmt.getDomain();
1875       isl_map *AccessDomain = MA->getAccessRelation();
1876       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1877       Write = isl_union_map_add_map(Write, AccessDomain);
1878     }
1879   }
1880   return isl_union_map_coalesce(Write);
1881 }
1882 
1883 __isl_give isl_union_map *Scop::getMayWrites() {
1884   isl_union_map *Write = isl_union_map_empty(getParamSpace());
1885 
1886   for (ScopStmt &Stmt : *this) {
1887     for (MemoryAccess *MA : Stmt) {
1888       if (!MA->isMayWrite())
1889         continue;
1890 
1891       isl_set *Domain = Stmt.getDomain();
1892       isl_map *AccessDomain = MA->getAccessRelation();
1893       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1894       Write = isl_union_map_add_map(Write, AccessDomain);
1895     }
1896   }
1897   return isl_union_map_coalesce(Write);
1898 }
1899 
1900 __isl_give isl_union_map *Scop::getWrites() {
1901   isl_union_map *Write = isl_union_map_empty(getParamSpace());
1902 
1903   for (ScopStmt &Stmt : *this) {
1904     for (MemoryAccess *MA : Stmt) {
1905       if (!MA->isWrite())
1906         continue;
1907 
1908       isl_set *Domain = Stmt.getDomain();
1909       isl_map *AccessDomain = MA->getAccessRelation();
1910       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1911       Write = isl_union_map_add_map(Write, AccessDomain);
1912     }
1913   }
1914   return isl_union_map_coalesce(Write);
1915 }
1916 
1917 __isl_give isl_union_map *Scop::getReads() {
1918   isl_union_map *Read = isl_union_map_empty(getParamSpace());
1919 
1920   for (ScopStmt &Stmt : *this) {
1921     for (MemoryAccess *MA : Stmt) {
1922       if (!MA->isRead())
1923         continue;
1924 
1925       isl_set *Domain = Stmt.getDomain();
1926       isl_map *AccessDomain = MA->getAccessRelation();
1927 
1928       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1929       Read = isl_union_map_add_map(Read, AccessDomain);
1930     }
1931   }
1932   return isl_union_map_coalesce(Read);
1933 }
1934 
1935 __isl_give isl_union_map *Scop::getSchedule() const {
1936   auto Tree = getScheduleTree();
1937   auto S = isl_schedule_get_map(Tree);
1938   isl_schedule_free(Tree);
1939   return S;
1940 }
1941 
1942 __isl_give isl_schedule *Scop::getScheduleTree() const {
1943   return isl_schedule_intersect_domain(isl_schedule_copy(Schedule),
1944                                        getDomains());
1945 }
1946 
1947 void Scop::setSchedule(__isl_take isl_union_map *NewSchedule) {
1948   auto *S = isl_schedule_from_domain(getDomains());
1949   S = isl_schedule_insert_partial_schedule(
1950       S, isl_multi_union_pw_aff_from_union_map(NewSchedule));
1951   isl_schedule_free(Schedule);
1952   Schedule = S;
1953 }
1954 
1955 void Scop::setScheduleTree(__isl_take isl_schedule *NewSchedule) {
1956   isl_schedule_free(Schedule);
1957   Schedule = NewSchedule;
1958 }
1959 
1960 bool Scop::restrictDomains(__isl_take isl_union_set *Domain) {
1961   bool Changed = false;
1962   for (ScopStmt &Stmt : *this) {
1963     isl_union_set *StmtDomain = isl_union_set_from_set(Stmt.getDomain());
1964     isl_union_set *NewStmtDomain = isl_union_set_intersect(
1965         isl_union_set_copy(StmtDomain), isl_union_set_copy(Domain));
1966 
1967     if (isl_union_set_is_subset(StmtDomain, NewStmtDomain)) {
1968       isl_union_set_free(StmtDomain);
1969       isl_union_set_free(NewStmtDomain);
1970       continue;
1971     }
1972 
1973     Changed = true;
1974 
1975     isl_union_set_free(StmtDomain);
1976     NewStmtDomain = isl_union_set_coalesce(NewStmtDomain);
1977 
1978     if (isl_union_set_is_empty(NewStmtDomain)) {
1979       Stmt.restrictDomain(isl_set_empty(Stmt.getDomainSpace()));
1980       isl_union_set_free(NewStmtDomain);
1981     } else
1982       Stmt.restrictDomain(isl_set_from_union_set(NewStmtDomain));
1983   }
1984   isl_union_set_free(Domain);
1985   return Changed;
1986 }
1987 
1988 ScalarEvolution *Scop::getSE() const { return SE; }
1989 
1990 bool Scop::isTrivialBB(BasicBlock *BB, TempScop &tempScop) {
1991   if (tempScop.getAccessFunctions(BB))
1992     return false;
1993 
1994   return true;
1995 }
1996 
1997 struct MapToDimensionDataTy {
1998   int N;
1999   isl_union_pw_multi_aff *Res;
2000 };
2001 
2002 // @brief Create a function that maps the elements of 'Set' to its N-th
2003 //        dimension.
2004 //
2005 // The result is added to 'User->Res'.
2006 //
2007 // @param Set The input set.
2008 // @param N   The dimension to map to.
2009 //
2010 // @returns   Zero if no error occurred, non-zero otherwise.
2011 static isl_stat mapToDimension_AddSet(__isl_take isl_set *Set, void *User) {
2012   struct MapToDimensionDataTy *Data = (struct MapToDimensionDataTy *)User;
2013   int Dim;
2014   isl_space *Space;
2015   isl_pw_multi_aff *PMA;
2016 
2017   Dim = isl_set_dim(Set, isl_dim_set);
2018   Space = isl_set_get_space(Set);
2019   PMA = isl_pw_multi_aff_project_out_map(Space, isl_dim_set, Data->N,
2020                                          Dim - Data->N);
2021   if (Data->N > 1)
2022     PMA = isl_pw_multi_aff_drop_dims(PMA, isl_dim_out, 0, Data->N - 1);
2023   Data->Res = isl_union_pw_multi_aff_add_pw_multi_aff(Data->Res, PMA);
2024 
2025   isl_set_free(Set);
2026 
2027   return isl_stat_ok;
2028 }
2029 
2030 // @brief Create a function that maps the elements of Domain to their Nth
2031 //        dimension.
2032 //
2033 // @param Domain The set of elements to map.
2034 // @param N      The dimension to map to.
2035 static __isl_give isl_multi_union_pw_aff *
2036 mapToDimension(__isl_take isl_union_set *Domain, int N) {
2037   struct MapToDimensionDataTy Data;
2038   isl_space *Space;
2039 
2040   Space = isl_union_set_get_space(Domain);
2041   Data.N = N;
2042   Data.Res = isl_union_pw_multi_aff_empty(Space);
2043   if (isl_union_set_foreach_set(Domain, &mapToDimension_AddSet, &Data) < 0)
2044     Data.Res = isl_union_pw_multi_aff_free(Data.Res);
2045 
2046   isl_union_set_free(Domain);
2047   return isl_multi_union_pw_aff_from_union_pw_multi_aff(Data.Res);
2048 }
2049 
2050 ScopStmt *Scop::addScopStmt(BasicBlock *BB, Region *R, TempScop &tempScop,
2051                             const Region &CurRegion,
2052                             SmallVectorImpl<Loop *> &NestLoops) {
2053   ScopStmt *Stmt;
2054   if (BB) {
2055     Stmts.emplace_back(*this, tempScop, CurRegion, *BB, NestLoops);
2056     Stmt = &Stmts.back();
2057     StmtMap[BB] = Stmt;
2058   } else {
2059     assert(R && "Either basic block or a region expected.");
2060     Stmts.emplace_back(*this, tempScop, CurRegion, *R, NestLoops);
2061     Stmt = &Stmts.back();
2062     for (BasicBlock *BB : R->blocks())
2063       StmtMap[BB] = Stmt;
2064   }
2065   return Stmt;
2066 }
2067 
2068 __isl_give isl_schedule *Scop::buildScop(TempScop &tempScop,
2069                                          const Region &CurRegion,
2070                                          SmallVectorImpl<Loop *> &NestLoops,
2071                                          LoopInfo &LI, ScopDetection &SD) {
2072   if (SD.isNonAffineSubRegion(&CurRegion, &getRegion())) {
2073     auto *Stmt = addScopStmt(nullptr, const_cast<Region *>(&CurRegion),
2074                              tempScop, CurRegion, NestLoops);
2075     auto *Domain = Stmt->getDomain();
2076     return isl_schedule_from_domain(isl_union_set_from_set(Domain));
2077   }
2078 
2079   Loop *L = castToLoop(CurRegion, LI);
2080 
2081   if (L)
2082     NestLoops.push_back(L);
2083 
2084   unsigned loopDepth = NestLoops.size();
2085   isl_schedule *Schedule = nullptr;
2086 
2087   for (Region::const_element_iterator I = CurRegion.element_begin(),
2088                                       E = CurRegion.element_end();
2089        I != E; ++I) {
2090     isl_schedule *StmtSchedule = nullptr;
2091     if (I->isSubRegion()) {
2092       StmtSchedule =
2093           buildScop(tempScop, *I->getNodeAs<Region>(), NestLoops, LI, SD);
2094     } else {
2095       BasicBlock *BB = I->getNodeAs<BasicBlock>();
2096 
2097       if (isTrivialBB(BB, tempScop)) {
2098         continue;
2099       } else {
2100         auto *Stmt = addScopStmt(BB, nullptr, tempScop, CurRegion, NestLoops);
2101         auto *Domain = Stmt->getDomain();
2102         StmtSchedule = isl_schedule_from_domain(isl_union_set_from_set(Domain));
2103       }
2104     }
2105 
2106     if (!Schedule)
2107       Schedule = StmtSchedule;
2108     else if (StmtSchedule)
2109       Schedule = isl_schedule_sequence(Schedule, StmtSchedule);
2110   }
2111 
2112   if (!L)
2113     return Schedule;
2114 
2115   auto *Domain = isl_schedule_get_domain(Schedule);
2116   if (!isl_union_set_is_empty(Domain)) {
2117     auto *MUPA = mapToDimension(isl_union_set_copy(Domain), loopDepth);
2118     Schedule = isl_schedule_insert_partial_schedule(Schedule, MUPA);
2119   }
2120   isl_union_set_free(Domain);
2121 
2122   NestLoops.pop_back();
2123   return Schedule;
2124 }
2125 
2126 ScopStmt *Scop::getStmtForBasicBlock(BasicBlock *BB) const {
2127   auto StmtMapIt = StmtMap.find(BB);
2128   if (StmtMapIt == StmtMap.end())
2129     return nullptr;
2130   return StmtMapIt->second;
2131 }
2132 
2133 //===----------------------------------------------------------------------===//
2134 ScopInfo::ScopInfo() : RegionPass(ID), scop(0) {
2135   ctx = isl_ctx_alloc();
2136   isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
2137 }
2138 
2139 ScopInfo::~ScopInfo() {
2140   clear();
2141   isl_ctx_free(ctx);
2142 }
2143 
2144 void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
2145   AU.addRequired<LoopInfoWrapperPass>();
2146   AU.addRequired<RegionInfoPass>();
2147   AU.addRequired<ScalarEvolution>();
2148   AU.addRequired<ScopDetection>();
2149   AU.addRequired<TempScopInfo>();
2150   AU.addRequired<AliasAnalysis>();
2151   AU.setPreservesAll();
2152 }
2153 
2154 bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
2155   LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
2156   AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
2157   ScopDetection &SD = getAnalysis<ScopDetection>();
2158   ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
2159 
2160   TempScop *tempScop = getAnalysis<TempScopInfo>().getTempScop(R);
2161 
2162   // This region is no Scop.
2163   if (!tempScop) {
2164     scop = nullptr;
2165     return false;
2166   }
2167 
2168   scop = new Scop(*tempScop, LI, SE, SD, ctx);
2169 
2170   DEBUG(scop->print(dbgs()));
2171 
2172   if (!PollyUseRuntimeAliasChecks) {
2173     // Statistics.
2174     ++ScopFound;
2175     if (scop->getMaxLoopDepth() > 0)
2176       ++RichScopFound;
2177     return false;
2178   }
2179 
2180   // If a problem occurs while building the alias groups we need to delete
2181   // this SCoP and pretend it wasn't valid in the first place.
2182   if (scop->buildAliasGroups(AA)) {
2183     // Statistics.
2184     ++ScopFound;
2185     if (scop->getMaxLoopDepth() > 0)
2186       ++RichScopFound;
2187     return false;
2188   }
2189 
2190   DEBUG(dbgs()
2191         << "\n\nNOTE: Run time checks for " << scop->getNameStr()
2192         << " could not be created as the number of parameters involved is too "
2193            "high. The SCoP will be "
2194            "dismissed.\nUse:\n\t--polly-rtc-max-parameters=X\nto adjust the "
2195            "maximal number of parameters but be advised that the compile time "
2196            "might increase exponentially.\n\n");
2197 
2198   delete scop;
2199   scop = nullptr;
2200   return false;
2201 }
2202 
2203 char ScopInfo::ID = 0;
2204 
2205 Pass *polly::createScopInfoPass() { return new ScopInfo(); }
2206 
2207 INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops",
2208                       "Polly - Create polyhedral description of Scops", false,
2209                       false);
2210 INITIALIZE_AG_DEPENDENCY(AliasAnalysis);
2211 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
2212 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
2213 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
2214 INITIALIZE_PASS_DEPENDENCY(ScopDetection);
2215 INITIALIZE_PASS_DEPENDENCY(TempScopInfo);
2216 INITIALIZE_PASS_END(ScopInfo, "polly-scops",
2217                     "Polly - Create polyhedral description of Scops", false,
2218                     false)
2219