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