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/CodeGen/BlockGenerators.h"
22 #include "polly/Options.h"
23 #include "polly/ScopInfo.h"
24 #include "polly/Support/GICHelper.h"
25 #include "polly/Support/SCEVValidator.h"
26 #include "polly/Support/ScopHelper.h"
27 #include "llvm/ADT/MapVector.h"
28 #include "llvm/ADT/PostOrderIterator.h"
29 #include "llvm/ADT/STLExtras.h"
30 #include "llvm/ADT/SetVector.h"
31 #include "llvm/ADT/Statistic.h"
32 #include "llvm/ADT/StringExtras.h"
33 #include "llvm/Analysis/AliasAnalysis.h"
34 #include "llvm/Analysis/LoopInfo.h"
35 #include "llvm/Analysis/LoopIterator.h"
36 #include "llvm/Analysis/RegionIterator.h"
37 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
38 #include "llvm/Support/Debug.h"
39 #include "isl/aff.h"
40 #include "isl/constraint.h"
41 #include "isl/local_space.h"
42 #include "isl/map.h"
43 #include "isl/options.h"
44 #include "isl/printer.h"
45 #include "isl/schedule.h"
46 #include "isl/schedule_node.h"
47 #include "isl/set.h"
48 #include "isl/union_map.h"
49 #include "isl/union_set.h"
50 #include "isl/val.h"
51 #include <sstream>
52 #include <string>
53 #include <vector>
54 
55 using namespace llvm;
56 using namespace polly;
57 
58 #define DEBUG_TYPE "polly-scops"
59 
60 STATISTIC(ScopFound, "Number of valid Scops");
61 STATISTIC(RichScopFound, "Number of Scops containing a loop");
62 
63 static cl::opt<bool> ModelReadOnlyScalars(
64     "polly-analyze-read-only-scalars",
65     cl::desc("Model read-only scalar values in the scop description"),
66     cl::Hidden, cl::ZeroOrMore, cl::init(true), cl::cat(PollyCategory));
67 
68 // Multiplicative reductions can be disabled separately as these kind of
69 // operations can overflow easily. Additive reductions and bit operations
70 // are in contrast pretty stable.
71 static cl::opt<bool> DisableMultiplicativeReductions(
72     "polly-disable-multiplicative-reductions",
73     cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore,
74     cl::init(false), cl::cat(PollyCategory));
75 
76 static cl::opt<unsigned> RunTimeChecksMaxParameters(
77     "polly-rtc-max-parameters",
78     cl::desc("The maximal number of parameters allowed in RTCs."), cl::Hidden,
79     cl::ZeroOrMore, cl::init(8), cl::cat(PollyCategory));
80 
81 static cl::opt<unsigned> RunTimeChecksMaxArraysPerGroup(
82     "polly-rtc-max-arrays-per-group",
83     cl::desc("The maximal number of arrays to compare in each alias group."),
84     cl::Hidden, cl::ZeroOrMore, cl::init(20), cl::cat(PollyCategory));
85 static cl::opt<std::string> UserContextStr(
86     "polly-context", cl::value_desc("isl parameter set"),
87     cl::desc("Provide additional constraints on the context parameters"),
88     cl::init(""), cl::cat(PollyCategory));
89 
90 static cl::opt<bool> DetectReductions("polly-detect-reductions",
91                                       cl::desc("Detect and exploit reductions"),
92                                       cl::Hidden, cl::ZeroOrMore,
93                                       cl::init(true), cl::cat(PollyCategory));
94 
95 //===----------------------------------------------------------------------===//
96 
97 // Create a sequence of two schedules. Either argument may be null and is
98 // interpreted as the empty schedule. Can also return null if both schedules are
99 // empty.
100 static __isl_give isl_schedule *
101 combineInSequence(__isl_take isl_schedule *Prev,
102                   __isl_take isl_schedule *Succ) {
103   if (!Prev)
104     return Succ;
105   if (!Succ)
106     return Prev;
107 
108   return isl_schedule_sequence(Prev, Succ);
109 }
110 
111 static __isl_give isl_set *addRangeBoundsToSet(__isl_take isl_set *S,
112                                                const ConstantRange &Range,
113                                                int dim,
114                                                enum isl_dim_type type) {
115   isl_val *V;
116   isl_ctx *ctx = isl_set_get_ctx(S);
117 
118   bool useLowerUpperBound = Range.isSignWrappedSet() && !Range.isFullSet();
119   const auto LB = useLowerUpperBound ? Range.getLower() : Range.getSignedMin();
120   V = isl_valFromAPInt(ctx, LB, true);
121   isl_set *SLB = isl_set_lower_bound_val(isl_set_copy(S), type, dim, V);
122 
123   const auto UB = useLowerUpperBound ? Range.getUpper() : Range.getSignedMax();
124   V = isl_valFromAPInt(ctx, UB, true);
125   if (useLowerUpperBound)
126     V = isl_val_sub_ui(V, 1);
127   isl_set *SUB = isl_set_upper_bound_val(S, type, dim, V);
128 
129   if (useLowerUpperBound)
130     return isl_set_union(SLB, SUB);
131   else
132     return isl_set_intersect(SLB, SUB);
133 }
134 
135 static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) {
136   LoadInst *BasePtrLI = dyn_cast<LoadInst>(BasePtr);
137   if (!BasePtrLI)
138     return nullptr;
139 
140   if (!S->getRegion().contains(BasePtrLI))
141     return nullptr;
142 
143   ScalarEvolution &SE = *S->getSE();
144 
145   auto *OriginBaseSCEV =
146       SE.getPointerBase(SE.getSCEV(BasePtrLI->getPointerOperand()));
147   if (!OriginBaseSCEV)
148     return nullptr;
149 
150   auto *OriginBaseSCEVUnknown = dyn_cast<SCEVUnknown>(OriginBaseSCEV);
151   if (!OriginBaseSCEVUnknown)
152     return nullptr;
153 
154   return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue());
155 }
156 
157 ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx,
158                              ArrayRef<const SCEV *> Sizes, bool IsPHI, Scop *S)
159     : BasePtr(BasePtr), ElementType(ElementType), IsPHI(IsPHI), S(*S) {
160   std::string BasePtrName =
161       getIslCompatibleName("MemRef_", BasePtr, IsPHI ? "__phi" : "");
162   Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
163 
164   updateSizes(Sizes);
165   BasePtrOriginSAI = identifyBasePtrOriginSAI(S, BasePtr);
166   if (BasePtrOriginSAI)
167     const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
168 }
169 
170 __isl_give isl_space *ScopArrayInfo::getSpace() const {
171   auto Space =
172       isl_space_set_alloc(isl_id_get_ctx(Id), 0, getNumberOfDimensions());
173   Space = isl_space_set_tuple_id(Space, isl_dim_set, isl_id_copy(Id));
174   return Space;
175 }
176 
177 void ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes) {
178 #ifndef NDEBUG
179   int SharedDims = std::min(NewSizes.size(), DimensionSizes.size());
180   int ExtraDimsNew = NewSizes.size() - SharedDims;
181   int ExtraDimsOld = DimensionSizes.size() - SharedDims;
182   for (int i = 0; i < SharedDims; i++) {
183     assert(NewSizes[i + ExtraDimsNew] == DimensionSizes[i + ExtraDimsOld] &&
184            "Array update with non-matching dimension sizes");
185   }
186 #endif
187 
188   DimensionSizes.clear();
189   DimensionSizes.insert(DimensionSizes.begin(), NewSizes.begin(),
190                         NewSizes.end());
191   for (isl_pw_aff *Size : DimensionSizesPw)
192     isl_pw_aff_free(Size);
193   DimensionSizesPw.clear();
194   for (const SCEV *Expr : DimensionSizes) {
195     isl_pw_aff *Size = S.getPwAff(Expr);
196     DimensionSizesPw.push_back(Size);
197   }
198 }
199 
200 ScopArrayInfo::~ScopArrayInfo() {
201   isl_id_free(Id);
202   for (isl_pw_aff *Size : DimensionSizesPw)
203     isl_pw_aff_free(Size);
204 }
205 
206 std::string ScopArrayInfo::getName() const { return isl_id_get_name(Id); }
207 
208 int ScopArrayInfo::getElemSizeInBytes() const {
209   return ElementType->getPrimitiveSizeInBits() / 8;
210 }
211 
212 isl_id *ScopArrayInfo::getBasePtrId() const { return isl_id_copy(Id); }
213 
214 void ScopArrayInfo::dump() const { print(errs()); }
215 
216 void ScopArrayInfo::print(raw_ostream &OS, bool SizeAsPwAff) const {
217   OS.indent(8) << *getElementType() << " " << getName() << "[*]";
218   for (unsigned u = 0; u < getNumberOfDimensions(); u++) {
219     OS << "[";
220 
221     if (SizeAsPwAff)
222       OS << " " << DimensionSizesPw[u] << " ";
223     else
224       OS << *DimensionSizes[u];
225 
226     OS << "]";
227   }
228 
229   if (BasePtrOriginSAI)
230     OS << " [BasePtrOrigin: " << BasePtrOriginSAI->getName() << "]";
231 
232   OS << " // Element size " << getElemSizeInBytes() << "\n";
233 }
234 
235 const ScopArrayInfo *
236 ScopArrayInfo::getFromAccessFunction(__isl_keep isl_pw_multi_aff *PMA) {
237   isl_id *Id = isl_pw_multi_aff_get_tuple_id(PMA, isl_dim_out);
238   assert(Id && "Output dimension didn't have an ID");
239   return getFromId(Id);
240 }
241 
242 const ScopArrayInfo *ScopArrayInfo::getFromId(isl_id *Id) {
243   void *User = isl_id_get_user(Id);
244   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
245   isl_id_free(Id);
246   return SAI;
247 }
248 
249 void MemoryAccess::updateDimensionality() {
250   auto ArraySpace = getScopArrayInfo()->getSpace();
251   auto AccessSpace = isl_space_range(isl_map_get_space(AccessRelation));
252 
253   auto DimsArray = isl_space_dim(ArraySpace, isl_dim_set);
254   auto DimsAccess = isl_space_dim(AccessSpace, isl_dim_set);
255   auto DimsMissing = DimsArray - DimsAccess;
256 
257   auto Map = isl_map_from_domain_and_range(isl_set_universe(AccessSpace),
258                                            isl_set_universe(ArraySpace));
259 
260   for (unsigned i = 0; i < DimsMissing; i++)
261     Map = isl_map_fix_si(Map, isl_dim_out, i, 0);
262 
263   for (unsigned i = DimsMissing; i < DimsArray; i++)
264     Map = isl_map_equate(Map, isl_dim_in, i - DimsMissing, isl_dim_out, i);
265 
266   AccessRelation = isl_map_apply_range(AccessRelation, Map);
267 }
268 
269 const std::string
270 MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
271   switch (RT) {
272   case MemoryAccess::RT_NONE:
273     llvm_unreachable("Requested a reduction operator string for a memory "
274                      "access which isn't a reduction");
275   case MemoryAccess::RT_ADD:
276     return "+";
277   case MemoryAccess::RT_MUL:
278     return "*";
279   case MemoryAccess::RT_BOR:
280     return "|";
281   case MemoryAccess::RT_BXOR:
282     return "^";
283   case MemoryAccess::RT_BAND:
284     return "&";
285   }
286   llvm_unreachable("Unknown reduction type");
287   return "";
288 }
289 
290 /// @brief Return the reduction type for a given binary operator
291 static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp,
292                                                     const Instruction *Load) {
293   if (!BinOp)
294     return MemoryAccess::RT_NONE;
295   switch (BinOp->getOpcode()) {
296   case Instruction::FAdd:
297     if (!BinOp->hasUnsafeAlgebra())
298       return MemoryAccess::RT_NONE;
299   // Fall through
300   case Instruction::Add:
301     return MemoryAccess::RT_ADD;
302   case Instruction::Or:
303     return MemoryAccess::RT_BOR;
304   case Instruction::Xor:
305     return MemoryAccess::RT_BXOR;
306   case Instruction::And:
307     return MemoryAccess::RT_BAND;
308   case Instruction::FMul:
309     if (!BinOp->hasUnsafeAlgebra())
310       return MemoryAccess::RT_NONE;
311   // Fall through
312   case Instruction::Mul:
313     if (DisableMultiplicativeReductions)
314       return MemoryAccess::RT_NONE;
315     return MemoryAccess::RT_MUL;
316   default:
317     return MemoryAccess::RT_NONE;
318   }
319 }
320 
321 /// @brief Derive the individual index expressions from a GEP instruction
322 ///
323 /// This function optimistically assumes the GEP references into a fixed size
324 /// array. If this is actually true, this function returns a list of array
325 /// subscript expressions as SCEV as well as a list of integers describing
326 /// the size of the individual array dimensions. Both lists have either equal
327 /// length of the size list is one element shorter in case there is no known
328 /// size available for the outermost array dimension.
329 ///
330 /// @param GEP The GetElementPtr instruction to analyze.
331 ///
332 /// @return A tuple with the subscript expressions and the dimension sizes.
333 static std::tuple<std::vector<const SCEV *>, std::vector<int>>
334 getIndexExpressionsFromGEP(GetElementPtrInst *GEP, ScalarEvolution &SE) {
335   std::vector<const SCEV *> Subscripts;
336   std::vector<int> Sizes;
337 
338   Type *Ty = GEP->getPointerOperandType();
339 
340   bool DroppedFirstDim = false;
341 
342   for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
343 
344     const SCEV *Expr = SE.getSCEV(GEP->getOperand(i));
345 
346     if (i == 1) {
347       if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
348         Ty = PtrTy->getElementType();
349       } else if (auto ArrayTy = dyn_cast<ArrayType>(Ty)) {
350         Ty = ArrayTy->getElementType();
351       } else {
352         Subscripts.clear();
353         Sizes.clear();
354         break;
355       }
356       if (auto Const = dyn_cast<SCEVConstant>(Expr))
357         if (Const->getValue()->isZero()) {
358           DroppedFirstDim = true;
359           continue;
360         }
361       Subscripts.push_back(Expr);
362       continue;
363     }
364 
365     auto ArrayTy = dyn_cast<ArrayType>(Ty);
366     if (!ArrayTy) {
367       Subscripts.clear();
368       Sizes.clear();
369       break;
370     }
371 
372     Subscripts.push_back(Expr);
373     if (!(DroppedFirstDim && i == 2))
374       Sizes.push_back(ArrayTy->getNumElements());
375 
376     Ty = ArrayTy->getElementType();
377   }
378 
379   return std::make_tuple(Subscripts, Sizes);
380 }
381 
382 MemoryAccess::~MemoryAccess() {
383   isl_id_free(Id);
384   isl_map_free(AccessRelation);
385   isl_map_free(NewAccessRelation);
386 }
387 
388 const ScopArrayInfo *MemoryAccess::getScopArrayInfo() const {
389   isl_id *ArrayId = getArrayId();
390   void *User = isl_id_get_user(ArrayId);
391   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
392   isl_id_free(ArrayId);
393   return SAI;
394 }
395 
396 __isl_give isl_id *MemoryAccess::getArrayId() const {
397   return isl_map_get_tuple_id(AccessRelation, isl_dim_out);
398 }
399 
400 __isl_give isl_pw_multi_aff *MemoryAccess::applyScheduleToAccessRelation(
401     __isl_take isl_union_map *USchedule) const {
402   isl_map *Schedule, *ScheduledAccRel;
403   isl_union_set *UDomain;
404 
405   UDomain = isl_union_set_from_set(getStatement()->getDomain());
406   USchedule = isl_union_map_intersect_domain(USchedule, UDomain);
407   Schedule = isl_map_from_union_map(USchedule);
408   ScheduledAccRel = isl_map_apply_domain(getAccessRelation(), Schedule);
409   return isl_pw_multi_aff_from_map(ScheduledAccRel);
410 }
411 
412 __isl_give isl_map *MemoryAccess::getOriginalAccessRelation() const {
413   return isl_map_copy(AccessRelation);
414 }
415 
416 std::string MemoryAccess::getOriginalAccessRelationStr() const {
417   return stringFromIslObj(AccessRelation);
418 }
419 
420 __isl_give isl_space *MemoryAccess::getOriginalAccessRelationSpace() const {
421   return isl_map_get_space(AccessRelation);
422 }
423 
424 __isl_give isl_map *MemoryAccess::getNewAccessRelation() const {
425   return isl_map_copy(NewAccessRelation);
426 }
427 
428 std::string MemoryAccess::getNewAccessRelationStr() const {
429   return stringFromIslObj(NewAccessRelation);
430 }
431 
432 __isl_give isl_basic_map *
433 MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
434   isl_space *Space = isl_space_set_alloc(Statement->getIslCtx(), 0, 1);
435   Space = isl_space_align_params(Space, Statement->getDomainSpace());
436 
437   return isl_basic_map_from_domain_and_range(
438       isl_basic_set_universe(Statement->getDomainSpace()),
439       isl_basic_set_universe(Space));
440 }
441 
442 // Formalize no out-of-bound access assumption
443 //
444 // When delinearizing array accesses we optimistically assume that the
445 // delinearized accesses do not access out of bound locations (the subscript
446 // expression of each array evaluates for each statement instance that is
447 // executed to a value that is larger than zero and strictly smaller than the
448 // size of the corresponding dimension). The only exception is the outermost
449 // dimension for which we do not need to assume any upper bound.  At this point
450 // we formalize this assumption to ensure that at code generation time the
451 // relevant run-time checks can be generated.
452 //
453 // To find the set of constraints necessary to avoid out of bound accesses, we
454 // first build the set of data locations that are not within array bounds. We
455 // then apply the reverse access relation to obtain the set of iterations that
456 // may contain invalid accesses and reduce this set of iterations to the ones
457 // that are actually executed by intersecting them with the domain of the
458 // statement. If we now project out all loop dimensions, we obtain a set of
459 // parameters that may cause statement instances to be executed that may
460 // possibly yield out of bound memory accesses. The complement of these
461 // constraints is the set of constraints that needs to be assumed to ensure such
462 // statement instances are never executed.
463 void MemoryAccess::assumeNoOutOfBound() {
464   isl_space *Space = isl_space_range(getOriginalAccessRelationSpace());
465   isl_set *Outside = isl_set_empty(isl_space_copy(Space));
466   for (int i = 1, Size = Subscripts.size(); i < Size; ++i) {
467     isl_local_space *LS = isl_local_space_from_space(isl_space_copy(Space));
468     isl_pw_aff *Var =
469         isl_pw_aff_var_on_domain(isl_local_space_copy(LS), isl_dim_set, i);
470     isl_pw_aff *Zero = isl_pw_aff_zero_on_domain(LS);
471 
472     isl_set *DimOutside;
473 
474     DimOutside = isl_pw_aff_lt_set(isl_pw_aff_copy(Var), Zero);
475     isl_pw_aff *SizeE = Statement->getPwAff(Sizes[i - 1]);
476 
477     SizeE = isl_pw_aff_drop_dims(SizeE, isl_dim_in, 0,
478                                  Statement->getNumIterators());
479     SizeE = isl_pw_aff_add_dims(SizeE, isl_dim_in,
480                                 isl_space_dim(Space, isl_dim_set));
481     SizeE = isl_pw_aff_set_tuple_id(SizeE, isl_dim_in,
482                                     isl_space_get_tuple_id(Space, isl_dim_set));
483 
484     DimOutside = isl_set_union(DimOutside, isl_pw_aff_le_set(SizeE, Var));
485 
486     Outside = isl_set_union(Outside, DimOutside);
487   }
488 
489   Outside = isl_set_apply(Outside, isl_map_reverse(getAccessRelation()));
490   Outside = isl_set_intersect(Outside, Statement->getDomain());
491   Outside = isl_set_params(Outside);
492 
493   // Remove divs to avoid the construction of overly complicated assumptions.
494   // Doing so increases the set of parameter combinations that are assumed to
495   // not appear. This is always save, but may make the resulting run-time check
496   // bail out more often than strictly necessary.
497   Outside = isl_set_remove_divs(Outside);
498   Outside = isl_set_complement(Outside);
499   Statement->getParent()->addAssumption(Outside);
500   isl_space_free(Space);
501 }
502 
503 void MemoryAccess::computeBoundsOnAccessRelation(unsigned ElementSize) {
504   ScalarEvolution *SE = Statement->getParent()->getSE();
505 
506   Value *Ptr = getPointerOperand(*getAccessInstruction());
507   if (!Ptr || !SE->isSCEVable(Ptr->getType()))
508     return;
509 
510   auto *PtrSCEV = SE->getSCEV(Ptr);
511   if (isa<SCEVCouldNotCompute>(PtrSCEV))
512     return;
513 
514   auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
515   if (BasePtrSCEV && !isa<SCEVCouldNotCompute>(BasePtrSCEV))
516     PtrSCEV = SE->getMinusSCEV(PtrSCEV, BasePtrSCEV);
517 
518   const ConstantRange &Range = SE->getSignedRange(PtrSCEV);
519   if (Range.isFullSet())
520     return;
521 
522   bool isWrapping = Range.isSignWrappedSet();
523   unsigned BW = Range.getBitWidth();
524   const auto LB = isWrapping ? Range.getLower() : Range.getSignedMin();
525   const auto UB = isWrapping ? Range.getUpper() : Range.getSignedMax();
526 
527   auto Min = LB.sdiv(APInt(BW, ElementSize));
528   auto Max = (UB - APInt(BW, 1)).sdiv(APInt(BW, ElementSize));
529 
530   isl_set *AccessRange = isl_map_range(isl_map_copy(AccessRelation));
531   AccessRange =
532       addRangeBoundsToSet(AccessRange, ConstantRange(Min, Max), 0, isl_dim_set);
533   AccessRelation = isl_map_intersect_range(AccessRelation, AccessRange);
534 }
535 
536 __isl_give isl_map *MemoryAccess::foldAccess(__isl_take isl_map *AccessRelation,
537                                              ScopStmt *Statement) {
538   int Size = Subscripts.size();
539 
540   for (int i = Size - 2; i >= 0; --i) {
541     isl_space *Space;
542     isl_map *MapOne, *MapTwo;
543     isl_pw_aff *DimSize = Statement->getPwAff(Sizes[i]);
544 
545     isl_space *SpaceSize = isl_pw_aff_get_space(DimSize);
546     isl_pw_aff_free(DimSize);
547     isl_id *ParamId = isl_space_get_dim_id(SpaceSize, isl_dim_param, 0);
548 
549     Space = isl_map_get_space(AccessRelation);
550     Space = isl_space_map_from_set(isl_space_range(Space));
551     Space = isl_space_align_params(Space, SpaceSize);
552 
553     int ParamLocation = isl_space_find_dim_by_id(Space, isl_dim_param, ParamId);
554     isl_id_free(ParamId);
555 
556     MapOne = isl_map_universe(isl_space_copy(Space));
557     for (int j = 0; j < Size; ++j)
558       MapOne = isl_map_equate(MapOne, isl_dim_in, j, isl_dim_out, j);
559     MapOne = isl_map_lower_bound_si(MapOne, isl_dim_in, i + 1, 0);
560 
561     MapTwo = isl_map_universe(isl_space_copy(Space));
562     for (int j = 0; j < Size; ++j)
563       if (j < i || j > i + 1)
564         MapTwo = isl_map_equate(MapTwo, isl_dim_in, j, isl_dim_out, j);
565 
566     isl_local_space *LS = isl_local_space_from_space(Space);
567     isl_constraint *C;
568     C = isl_equality_alloc(isl_local_space_copy(LS));
569     C = isl_constraint_set_constant_si(C, -1);
570     C = isl_constraint_set_coefficient_si(C, isl_dim_in, i, 1);
571     C = isl_constraint_set_coefficient_si(C, isl_dim_out, i, -1);
572     MapTwo = isl_map_add_constraint(MapTwo, C);
573     C = isl_equality_alloc(LS);
574     C = isl_constraint_set_coefficient_si(C, isl_dim_in, i + 1, 1);
575     C = isl_constraint_set_coefficient_si(C, isl_dim_out, i + 1, -1);
576     C = isl_constraint_set_coefficient_si(C, isl_dim_param, ParamLocation, 1);
577     MapTwo = isl_map_add_constraint(MapTwo, C);
578     MapTwo = isl_map_upper_bound_si(MapTwo, isl_dim_in, i + 1, -1);
579 
580     MapOne = isl_map_union(MapOne, MapTwo);
581     AccessRelation = isl_map_apply_range(AccessRelation, MapOne);
582   }
583   return AccessRelation;
584 }
585 
586 void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) {
587   assert(!AccessRelation && "AccessReltation already built");
588 
589   isl_ctx *Ctx = isl_id_get_ctx(Id);
590   isl_id *BaseAddrId = SAI->getBasePtrId();
591 
592   if (!isAffine()) {
593     // We overapproximate non-affine accesses with a possible access to the
594     // whole array. For read accesses it does not make a difference, if an
595     // access must or may happen. However, for write accesses it is important to
596     // differentiate between writes that must happen and writes that may happen.
597     AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
598     AccessRelation =
599         isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
600 
601     computeBoundsOnAccessRelation(getElemSizeInBytes());
602     return;
603   }
604 
605   isl_space *Space = isl_space_alloc(Ctx, 0, Statement->getNumIterators(), 0);
606   AccessRelation = isl_map_universe(Space);
607 
608   for (int i = 0, Size = Subscripts.size(); i < Size; ++i) {
609     isl_pw_aff *Affine = Statement->getPwAff(Subscripts[i]);
610 
611     if (Size == 1) {
612       // For the non delinearized arrays, divide the access function of the last
613       // subscript by the size of the elements in the array.
614       //
615       // A stride one array access in C expressed as A[i] is expressed in
616       // LLVM-IR as something like A[i * elementsize]. This hides the fact that
617       // two subsequent values of 'i' index two values that are stored next to
618       // each other in memory. By this division we make this characteristic
619       // obvious again.
620       isl_val *v = isl_val_int_from_si(Ctx, getElemSizeInBytes());
621       Affine = isl_pw_aff_scale_down_val(Affine, v);
622     }
623 
624     isl_map *SubscriptMap = isl_map_from_pw_aff(Affine);
625 
626     AccessRelation = isl_map_flat_range_product(AccessRelation, SubscriptMap);
627   }
628 
629   if (Sizes.size() > 1 && !isa<SCEVConstant>(Sizes[0]))
630     AccessRelation = foldAccess(AccessRelation, Statement);
631 
632   Space = Statement->getDomainSpace();
633   AccessRelation = isl_map_set_tuple_id(
634       AccessRelation, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
635   AccessRelation =
636       isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
637 
638   assumeNoOutOfBound();
639   AccessRelation = isl_map_gist_domain(AccessRelation, Statement->getDomain());
640   isl_space_free(Space);
641 }
642 
643 MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
644                            __isl_take isl_id *Id, AccessType Type,
645                            Value *BaseAddress, unsigned ElemBytes, bool Affine,
646                            ArrayRef<const SCEV *> Subscripts,
647                            ArrayRef<const SCEV *> Sizes, Value *AccessValue,
648                            AccessOrigin Origin, StringRef BaseName)
649     : Id(Id), Origin(Origin), AccType(Type), RedType(RT_NONE), Statement(Stmt),
650       BaseAddr(BaseAddress), BaseName(BaseName), ElemBytes(ElemBytes),
651       Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst),
652       AccessValue(AccessValue), IsAffine(Affine),
653       Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(nullptr),
654       NewAccessRelation(nullptr) {}
655 
656 void MemoryAccess::realignParams() {
657   isl_space *ParamSpace = Statement->getParent()->getParamSpace();
658   AccessRelation = isl_map_align_params(AccessRelation, ParamSpace);
659 }
660 
661 const std::string MemoryAccess::getReductionOperatorStr() const {
662   return MemoryAccess::getReductionOperatorStr(getReductionType());
663 }
664 
665 __isl_give isl_id *MemoryAccess::getId() const { return isl_id_copy(Id); }
666 
667 raw_ostream &polly::operator<<(raw_ostream &OS,
668                                MemoryAccess::ReductionType RT) {
669   if (RT == MemoryAccess::RT_NONE)
670     OS << "NONE";
671   else
672     OS << MemoryAccess::getReductionOperatorStr(RT);
673   return OS;
674 }
675 
676 void MemoryAccess::print(raw_ostream &OS) const {
677   switch (AccType) {
678   case READ:
679     OS.indent(12) << "ReadAccess :=\t";
680     break;
681   case MUST_WRITE:
682     OS.indent(12) << "MustWriteAccess :=\t";
683     break;
684   case MAY_WRITE:
685     OS.indent(12) << "MayWriteAccess :=\t";
686     break;
687   }
688   OS << "[Reduction Type: " << getReductionType() << "] ";
689   OS << "[Scalar: " << isImplicit() << "]\n";
690   OS.indent(16) << getOriginalAccessRelationStr() << ";\n";
691   if (hasNewAccessRelation())
692     OS.indent(11) << "new: " << getNewAccessRelationStr() << ";\n";
693 }
694 
695 void MemoryAccess::dump() const { print(errs()); }
696 
697 // Create a map in the size of the provided set domain, that maps from the
698 // one element of the provided set domain to another element of the provided
699 // set domain.
700 // The mapping is limited to all points that are equal in all but the last
701 // dimension and for which the last dimension of the input is strict smaller
702 // than the last dimension of the output.
703 //
704 //   getEqualAndLarger(set[i0, i1, ..., iX]):
705 //
706 //   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
707 //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
708 //
709 static isl_map *getEqualAndLarger(isl_space *setDomain) {
710   isl_space *Space = isl_space_map_from_set(setDomain);
711   isl_map *Map = isl_map_universe(Space);
712   unsigned lastDimension = isl_map_dim(Map, isl_dim_in) - 1;
713 
714   // Set all but the last dimension to be equal for the input and output
715   //
716   //   input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
717   //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
718   for (unsigned i = 0; i < lastDimension; ++i)
719     Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
720 
721   // Set the last dimension of the input to be strict smaller than the
722   // last dimension of the output.
723   //
724   //   input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
725   Map = isl_map_order_lt(Map, isl_dim_in, lastDimension, isl_dim_out,
726                          lastDimension);
727   return Map;
728 }
729 
730 __isl_give isl_set *
731 MemoryAccess::getStride(__isl_take const isl_map *Schedule) const {
732   isl_map *S = const_cast<isl_map *>(Schedule);
733   isl_map *AccessRelation = getAccessRelation();
734   isl_space *Space = isl_space_range(isl_map_get_space(S));
735   isl_map *NextScatt = getEqualAndLarger(Space);
736 
737   S = isl_map_reverse(S);
738   NextScatt = isl_map_lexmin(NextScatt);
739 
740   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(S));
741   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(AccessRelation));
742   NextScatt = isl_map_apply_domain(NextScatt, S);
743   NextScatt = isl_map_apply_domain(NextScatt, AccessRelation);
744 
745   isl_set *Deltas = isl_map_deltas(NextScatt);
746   return Deltas;
747 }
748 
749 bool MemoryAccess::isStrideX(__isl_take const isl_map *Schedule,
750                              int StrideWidth) const {
751   isl_set *Stride, *StrideX;
752   bool IsStrideX;
753 
754   Stride = getStride(Schedule);
755   StrideX = isl_set_universe(isl_set_get_space(Stride));
756   for (unsigned i = 0; i < isl_set_dim(StrideX, isl_dim_set) - 1; i++)
757     StrideX = isl_set_fix_si(StrideX, isl_dim_set, i, 0);
758   StrideX = isl_set_fix_si(StrideX, isl_dim_set,
759                            isl_set_dim(StrideX, isl_dim_set) - 1, StrideWidth);
760   IsStrideX = isl_set_is_subset(Stride, StrideX);
761 
762   isl_set_free(StrideX);
763   isl_set_free(Stride);
764 
765   return IsStrideX;
766 }
767 
768 bool MemoryAccess::isStrideZero(const isl_map *Schedule) const {
769   return isStrideX(Schedule, 0);
770 }
771 
772 bool MemoryAccess::isStrideOne(const isl_map *Schedule) const {
773   return isStrideX(Schedule, 1);
774 }
775 
776 void MemoryAccess::setNewAccessRelation(isl_map *NewAccess) {
777   isl_map_free(NewAccessRelation);
778   NewAccessRelation = NewAccess;
779 }
780 
781 //===----------------------------------------------------------------------===//
782 
783 isl_map *ScopStmt::getSchedule() const {
784   isl_set *Domain = getDomain();
785   if (isl_set_is_empty(Domain)) {
786     isl_set_free(Domain);
787     return isl_map_from_aff(
788         isl_aff_zero_on_domain(isl_local_space_from_space(getDomainSpace())));
789   }
790   auto *Schedule = getParent()->getSchedule();
791   Schedule = isl_union_map_intersect_domain(
792       Schedule, isl_union_set_from_set(isl_set_copy(Domain)));
793   if (isl_union_map_is_empty(Schedule)) {
794     isl_set_free(Domain);
795     isl_union_map_free(Schedule);
796     return isl_map_from_aff(
797         isl_aff_zero_on_domain(isl_local_space_from_space(getDomainSpace())));
798   }
799   auto *M = isl_map_from_union_map(Schedule);
800   M = isl_map_coalesce(M);
801   M = isl_map_gist_domain(M, Domain);
802   M = isl_map_coalesce(M);
803   return M;
804 }
805 
806 __isl_give isl_pw_aff *ScopStmt::getPwAff(const SCEV *E) {
807   return getParent()->getPwAff(E, isBlockStmt() ? getBasicBlock()
808                                                 : getRegion()->getEntry());
809 }
810 
811 void ScopStmt::restrictDomain(__isl_take isl_set *NewDomain) {
812   assert(isl_set_is_subset(NewDomain, Domain) &&
813          "New domain is not a subset of old domain!");
814   isl_set_free(Domain);
815   Domain = NewDomain;
816 }
817 
818 void ScopStmt::buildAccessRelations() {
819   for (MemoryAccess *Access : MemAccs) {
820     Type *ElementType = Access->getAccessValue()->getType();
821 
822     const ScopArrayInfo *SAI = getParent()->getOrCreateScopArrayInfo(
823         Access->getBaseAddr(), ElementType, Access->Sizes, Access->isPHI());
824 
825     Access->buildAccessRelation(SAI);
826   }
827 }
828 
829 void ScopStmt::addAccess(MemoryAccess *Access) {
830   Instruction *AccessInst = Access->getAccessInstruction();
831 
832   MemoryAccessList *&MAL = InstructionToAccess[AccessInst];
833   if (!MAL)
834     MAL = new MemoryAccessList();
835   MAL->emplace_front(Access);
836   MemAccs.push_back(MAL->front());
837 }
838 
839 void ScopStmt::realignParams() {
840   for (MemoryAccess *MA : *this)
841     MA->realignParams();
842 
843   Domain = isl_set_align_params(Domain, Parent.getParamSpace());
844 }
845 
846 /// @brief Add @p BSet to the set @p User if @p BSet is bounded.
847 static isl_stat collectBoundedParts(__isl_take isl_basic_set *BSet,
848                                     void *User) {
849   isl_set **BoundedParts = static_cast<isl_set **>(User);
850   if (isl_basic_set_is_bounded(BSet))
851     *BoundedParts = isl_set_union(*BoundedParts, isl_set_from_basic_set(BSet));
852   else
853     isl_basic_set_free(BSet);
854   return isl_stat_ok;
855 }
856 
857 /// @brief Return the bounded parts of @p S.
858 static __isl_give isl_set *collectBoundedParts(__isl_take isl_set *S) {
859   isl_set *BoundedParts = isl_set_empty(isl_set_get_space(S));
860   isl_set_foreach_basic_set(S, collectBoundedParts, &BoundedParts);
861   isl_set_free(S);
862   return BoundedParts;
863 }
864 
865 /// @brief Compute the (un)bounded parts of @p S wrt. to dimension @p Dim.
866 ///
867 /// @returns A separation of @p S into first an unbounded then a bounded subset,
868 ///          both with regards to the dimension @p Dim.
869 static std::pair<__isl_give isl_set *, __isl_give isl_set *>
870 partitionSetParts(__isl_take isl_set *S, unsigned Dim) {
871 
872   for (unsigned u = 0, e = isl_set_n_dim(S); u < e; u++)
873     S = isl_set_lower_bound_si(S, isl_dim_set, u, 0);
874 
875   unsigned NumDimsS = isl_set_n_dim(S);
876   isl_set *OnlyDimS = isl_set_copy(S);
877 
878   // Remove dimensions that are greater than Dim as they are not interesting.
879   assert(NumDimsS >= Dim + 1);
880   OnlyDimS =
881       isl_set_project_out(OnlyDimS, isl_dim_set, Dim + 1, NumDimsS - Dim - 1);
882 
883   // Create artificial parametric upper bounds for dimensions smaller than Dim
884   // as we are not interested in them.
885   OnlyDimS = isl_set_insert_dims(OnlyDimS, isl_dim_param, 0, Dim);
886   for (unsigned u = 0; u < Dim; u++) {
887     isl_constraint *C = isl_inequality_alloc(
888         isl_local_space_from_space(isl_set_get_space(OnlyDimS)));
889     C = isl_constraint_set_coefficient_si(C, isl_dim_param, u, 1);
890     C = isl_constraint_set_coefficient_si(C, isl_dim_set, u, -1);
891     OnlyDimS = isl_set_add_constraint(OnlyDimS, C);
892   }
893 
894   // Collect all bounded parts of OnlyDimS.
895   isl_set *BoundedParts = collectBoundedParts(OnlyDimS);
896 
897   // Create the dimensions greater than Dim again.
898   BoundedParts = isl_set_insert_dims(BoundedParts, isl_dim_set, Dim + 1,
899                                      NumDimsS - Dim - 1);
900 
901   // Remove the artificial upper bound parameters again.
902   BoundedParts = isl_set_remove_dims(BoundedParts, isl_dim_param, 0, Dim);
903 
904   isl_set *UnboundedParts = isl_set_subtract(S, isl_set_copy(BoundedParts));
905   return std::make_pair(UnboundedParts, BoundedParts);
906 }
907 
908 /// @brief Set the dimension Ids from @p From in @p To.
909 static __isl_give isl_set *setDimensionIds(__isl_keep isl_set *From,
910                                            __isl_take isl_set *To) {
911   for (unsigned u = 0, e = isl_set_n_dim(From); u < e; u++) {
912     isl_id *DimId = isl_set_get_dim_id(From, isl_dim_set, u);
913     To = isl_set_set_dim_id(To, isl_dim_set, u, DimId);
914   }
915   return To;
916 }
917 
918 /// @brief Create the conditions under which @p L @p Pred @p R is true.
919 static __isl_give isl_set *buildConditionSet(ICmpInst::Predicate Pred,
920                                              __isl_take isl_pw_aff *L,
921                                              __isl_take isl_pw_aff *R) {
922   switch (Pred) {
923   case ICmpInst::ICMP_EQ:
924     return isl_pw_aff_eq_set(L, R);
925   case ICmpInst::ICMP_NE:
926     return isl_pw_aff_ne_set(L, R);
927   case ICmpInst::ICMP_SLT:
928     return isl_pw_aff_lt_set(L, R);
929   case ICmpInst::ICMP_SLE:
930     return isl_pw_aff_le_set(L, R);
931   case ICmpInst::ICMP_SGT:
932     return isl_pw_aff_gt_set(L, R);
933   case ICmpInst::ICMP_SGE:
934     return isl_pw_aff_ge_set(L, R);
935   case ICmpInst::ICMP_ULT:
936     return isl_pw_aff_lt_set(L, R);
937   case ICmpInst::ICMP_UGT:
938     return isl_pw_aff_gt_set(L, R);
939   case ICmpInst::ICMP_ULE:
940     return isl_pw_aff_le_set(L, R);
941   case ICmpInst::ICMP_UGE:
942     return isl_pw_aff_ge_set(L, R);
943   default:
944     llvm_unreachable("Non integer predicate not supported");
945   }
946 }
947 
948 /// @brief Create the conditions under which @p L @p Pred @p R is true.
949 ///
950 /// Helper function that will make sure the dimensions of the result have the
951 /// same isl_id's as the @p Domain.
952 static __isl_give isl_set *buildConditionSet(ICmpInst::Predicate Pred,
953                                              __isl_take isl_pw_aff *L,
954                                              __isl_take isl_pw_aff *R,
955                                              __isl_keep isl_set *Domain) {
956   isl_set *ConsequenceCondSet = buildConditionSet(Pred, L, R);
957   return setDimensionIds(Domain, ConsequenceCondSet);
958 }
959 
960 /// @brief Build the conditions sets for the switch @p SI in the @p Domain.
961 ///
962 /// This will fill @p ConditionSets with the conditions under which control
963 /// will be moved from @p SI to its successors. Hence, @p ConditionSets will
964 /// have as many elements as @p SI has successors.
965 static void
966 buildConditionSets(Scop &S, SwitchInst *SI, Loop *L, __isl_keep isl_set *Domain,
967                    SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
968 
969   Value *Condition = getConditionFromTerminator(SI);
970   assert(Condition && "No condition for switch");
971 
972   ScalarEvolution &SE = *S.getSE();
973   BasicBlock *BB = SI->getParent();
974   isl_pw_aff *LHS, *RHS;
975   LHS = S.getPwAff(SE.getSCEVAtScope(Condition, L), BB);
976 
977   unsigned NumSuccessors = SI->getNumSuccessors();
978   ConditionSets.resize(NumSuccessors);
979   for (auto &Case : SI->cases()) {
980     unsigned Idx = Case.getSuccessorIndex();
981     ConstantInt *CaseValue = Case.getCaseValue();
982 
983     RHS = S.getPwAff(SE.getSCEV(CaseValue), BB);
984     isl_set *CaseConditionSet =
985         buildConditionSet(ICmpInst::ICMP_EQ, isl_pw_aff_copy(LHS), RHS, Domain);
986     ConditionSets[Idx] = isl_set_coalesce(
987         isl_set_intersect(CaseConditionSet, isl_set_copy(Domain)));
988   }
989 
990   assert(ConditionSets[0] == nullptr && "Default condition set was set");
991   isl_set *ConditionSetUnion = isl_set_copy(ConditionSets[1]);
992   for (unsigned u = 2; u < NumSuccessors; u++)
993     ConditionSetUnion =
994         isl_set_union(ConditionSetUnion, isl_set_copy(ConditionSets[u]));
995   ConditionSets[0] = setDimensionIds(
996       Domain, isl_set_subtract(isl_set_copy(Domain), ConditionSetUnion));
997 
998   S.markAsOptimized();
999   isl_pw_aff_free(LHS);
1000 }
1001 
1002 /// @brief Build the conditions sets for the terminator @p TI in the @p Domain.
1003 ///
1004 /// This will fill @p ConditionSets with the conditions under which control
1005 /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
1006 /// have as many elements as @p TI has successors.
1007 static void
1008 buildConditionSets(Scop &S, TerminatorInst *TI, Loop *L,
1009                    __isl_keep isl_set *Domain,
1010                    SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
1011 
1012   if (SwitchInst *SI = dyn_cast<SwitchInst>(TI))
1013     return buildConditionSets(S, SI, L, Domain, ConditionSets);
1014 
1015   assert(isa<BranchInst>(TI) && "Terminator was neither branch nor switch.");
1016 
1017   if (TI->getNumSuccessors() == 1) {
1018     ConditionSets.push_back(isl_set_copy(Domain));
1019     return;
1020   }
1021 
1022   Value *Condition = getConditionFromTerminator(TI);
1023   assert(Condition && "No condition for Terminator");
1024 
1025   isl_set *ConsequenceCondSet = nullptr;
1026   if (auto *CCond = dyn_cast<ConstantInt>(Condition)) {
1027     if (CCond->isZero())
1028       ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain));
1029     else
1030       ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain));
1031   } else {
1032     auto *ICond = dyn_cast<ICmpInst>(Condition);
1033     assert(ICond &&
1034            "Condition of exiting branch was neither constant nor ICmp!");
1035 
1036     ScalarEvolution &SE = *S.getSE();
1037     BasicBlock *BB = TI->getParent();
1038     isl_pw_aff *LHS, *RHS;
1039     LHS = S.getPwAff(SE.getSCEVAtScope(ICond->getOperand(0), L), BB);
1040     RHS = S.getPwAff(SE.getSCEVAtScope(ICond->getOperand(1), L), BB);
1041     ConsequenceCondSet =
1042         buildConditionSet(ICond->getPredicate(), LHS, RHS, Domain);
1043   }
1044 
1045   assert(ConsequenceCondSet);
1046   isl_set *AlternativeCondSet =
1047       isl_set_complement(isl_set_copy(ConsequenceCondSet));
1048 
1049   ConditionSets.push_back(isl_set_coalesce(
1050       isl_set_intersect(ConsequenceCondSet, isl_set_copy(Domain))));
1051   ConditionSets.push_back(isl_set_coalesce(
1052       isl_set_intersect(AlternativeCondSet, isl_set_copy(Domain))));
1053 }
1054 
1055 void ScopStmt::buildDomain() {
1056   isl_id *Id;
1057 
1058   Id = isl_id_alloc(getIslCtx(), getBaseName(), this);
1059 
1060   Domain = getParent()->getDomainConditions(this);
1061   Domain = isl_set_set_tuple_id(Domain, Id);
1062 }
1063 
1064 void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP) {
1065   isl_ctx *Ctx = Parent.getIslCtx();
1066   isl_local_space *LSpace = isl_local_space_from_space(getDomainSpace());
1067   Type *Ty = GEP->getPointerOperandType();
1068   ScalarEvolution &SE = *Parent.getSE();
1069 
1070   std::vector<const SCEV *> Subscripts;
1071   std::vector<int> Sizes;
1072 
1073   std::tie(Subscripts, Sizes) = getIndexExpressionsFromGEP(GEP, SE);
1074 
1075   if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
1076     Ty = PtrTy->getElementType();
1077   }
1078 
1079   int IndexOffset = Subscripts.size() - Sizes.size();
1080 
1081   assert(IndexOffset <= 1 && "Unexpected large index offset");
1082 
1083   for (size_t i = 0; i < Sizes.size(); i++) {
1084     auto Expr = Subscripts[i + IndexOffset];
1085     auto Size = Sizes[i];
1086 
1087     if (!isAffineExpr(&Parent.getRegion(), Expr, SE))
1088       continue;
1089 
1090     isl_pw_aff *AccessOffset = getPwAff(Expr);
1091     AccessOffset =
1092         isl_pw_aff_set_tuple_id(AccessOffset, isl_dim_in, getDomainId());
1093 
1094     isl_pw_aff *DimSize = isl_pw_aff_from_aff(isl_aff_val_on_domain(
1095         isl_local_space_copy(LSpace), isl_val_int_from_si(Ctx, Size)));
1096 
1097     isl_set *OutOfBound = isl_pw_aff_ge_set(AccessOffset, DimSize);
1098     OutOfBound = isl_set_intersect(getDomain(), OutOfBound);
1099     OutOfBound = isl_set_params(OutOfBound);
1100     isl_set *InBound = isl_set_complement(OutOfBound);
1101     isl_set *Executed = isl_set_params(getDomain());
1102 
1103     // A => B == !A or B
1104     isl_set *InBoundIfExecuted =
1105         isl_set_union(isl_set_complement(Executed), InBound);
1106 
1107     Parent.addAssumption(InBoundIfExecuted);
1108   }
1109 
1110   isl_local_space_free(LSpace);
1111 }
1112 
1113 void ScopStmt::deriveAssumptions(BasicBlock *Block) {
1114   for (Instruction &Inst : *Block)
1115     if (auto *GEP = dyn_cast<GetElementPtrInst>(&Inst))
1116       deriveAssumptionsFromGEP(GEP);
1117 }
1118 
1119 void ScopStmt::collectSurroundingLoops() {
1120   for (unsigned u = 0, e = isl_set_n_dim(Domain); u < e; u++) {
1121     isl_id *DimId = isl_set_get_dim_id(Domain, isl_dim_set, u);
1122     NestLoops.push_back(static_cast<Loop *>(isl_id_get_user(DimId)));
1123     isl_id_free(DimId);
1124   }
1125 }
1126 
1127 ScopStmt::ScopStmt(Scop &parent, Region &R)
1128     : Parent(parent), Domain(nullptr), BB(nullptr), R(&R), Build(nullptr) {
1129 
1130   BaseName = getIslCompatibleName("Stmt_", R.getNameStr(), "");
1131 }
1132 
1133 ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb)
1134     : Parent(parent), Domain(nullptr), BB(&bb), R(nullptr), Build(nullptr) {
1135 
1136   BaseName = getIslCompatibleName("Stmt_", &bb, "");
1137 }
1138 
1139 void ScopStmt::init() {
1140   assert(!Domain && "init must be called only once");
1141 
1142   buildDomain();
1143   collectSurroundingLoops();
1144   buildAccessRelations();
1145 
1146   if (BB) {
1147     deriveAssumptions(BB);
1148   } else {
1149     for (BasicBlock *Block : R->blocks()) {
1150       deriveAssumptions(Block);
1151     }
1152   }
1153 
1154   if (DetectReductions)
1155     checkForReductions();
1156 }
1157 
1158 /// @brief Collect loads which might form a reduction chain with @p StoreMA
1159 ///
1160 /// Check if the stored value for @p StoreMA is a binary operator with one or
1161 /// two loads as operands. If the binary operand is commutative & associative,
1162 /// used only once (by @p StoreMA) and its load operands are also used only
1163 /// once, we have found a possible reduction chain. It starts at an operand
1164 /// load and includes the binary operator and @p StoreMA.
1165 ///
1166 /// Note: We allow only one use to ensure the load and binary operator cannot
1167 ///       escape this block or into any other store except @p StoreMA.
1168 void ScopStmt::collectCandiateReductionLoads(
1169     MemoryAccess *StoreMA, SmallVectorImpl<MemoryAccess *> &Loads) {
1170   auto *Store = dyn_cast<StoreInst>(StoreMA->getAccessInstruction());
1171   if (!Store)
1172     return;
1173 
1174   // Skip if there is not one binary operator between the load and the store
1175   auto *BinOp = dyn_cast<BinaryOperator>(Store->getValueOperand());
1176   if (!BinOp)
1177     return;
1178 
1179   // Skip if the binary operators has multiple uses
1180   if (BinOp->getNumUses() != 1)
1181     return;
1182 
1183   // Skip if the opcode of the binary operator is not commutative/associative
1184   if (!BinOp->isCommutative() || !BinOp->isAssociative())
1185     return;
1186 
1187   // Skip if the binary operator is outside the current SCoP
1188   if (BinOp->getParent() != Store->getParent())
1189     return;
1190 
1191   // Skip if it is a multiplicative reduction and we disabled them
1192   if (DisableMultiplicativeReductions &&
1193       (BinOp->getOpcode() == Instruction::Mul ||
1194        BinOp->getOpcode() == Instruction::FMul))
1195     return;
1196 
1197   // Check the binary operator operands for a candidate load
1198   auto *PossibleLoad0 = dyn_cast<LoadInst>(BinOp->getOperand(0));
1199   auto *PossibleLoad1 = dyn_cast<LoadInst>(BinOp->getOperand(1));
1200   if (!PossibleLoad0 && !PossibleLoad1)
1201     return;
1202 
1203   // A load is only a candidate if it cannot escape (thus has only this use)
1204   if (PossibleLoad0 && PossibleLoad0->getNumUses() == 1)
1205     if (PossibleLoad0->getParent() == Store->getParent())
1206       Loads.push_back(lookupAccessFor(PossibleLoad0));
1207   if (PossibleLoad1 && PossibleLoad1->getNumUses() == 1)
1208     if (PossibleLoad1->getParent() == Store->getParent())
1209       Loads.push_back(lookupAccessFor(PossibleLoad1));
1210 }
1211 
1212 /// @brief Check for reductions in this ScopStmt
1213 ///
1214 /// Iterate over all store memory accesses and check for valid binary reduction
1215 /// like chains. For all candidates we check if they have the same base address
1216 /// and there are no other accesses which overlap with them. The base address
1217 /// check rules out impossible reductions candidates early. The overlap check,
1218 /// together with the "only one user" check in collectCandiateReductionLoads,
1219 /// guarantees that none of the intermediate results will escape during
1220 /// execution of the loop nest. We basically check here that no other memory
1221 /// access can access the same memory as the potential reduction.
1222 void ScopStmt::checkForReductions() {
1223   SmallVector<MemoryAccess *, 2> Loads;
1224   SmallVector<std::pair<MemoryAccess *, MemoryAccess *>, 4> Candidates;
1225 
1226   // First collect candidate load-store reduction chains by iterating over all
1227   // stores and collecting possible reduction loads.
1228   for (MemoryAccess *StoreMA : MemAccs) {
1229     if (StoreMA->isRead())
1230       continue;
1231 
1232     Loads.clear();
1233     collectCandiateReductionLoads(StoreMA, Loads);
1234     for (MemoryAccess *LoadMA : Loads)
1235       Candidates.push_back(std::make_pair(LoadMA, StoreMA));
1236   }
1237 
1238   // Then check each possible candidate pair.
1239   for (const auto &CandidatePair : Candidates) {
1240     bool Valid = true;
1241     isl_map *LoadAccs = CandidatePair.first->getAccessRelation();
1242     isl_map *StoreAccs = CandidatePair.second->getAccessRelation();
1243 
1244     // Skip those with obviously unequal base addresses.
1245     if (!isl_map_has_equal_space(LoadAccs, StoreAccs)) {
1246       isl_map_free(LoadAccs);
1247       isl_map_free(StoreAccs);
1248       continue;
1249     }
1250 
1251     // And check if the remaining for overlap with other memory accesses.
1252     isl_map *AllAccsRel = isl_map_union(LoadAccs, StoreAccs);
1253     AllAccsRel = isl_map_intersect_domain(AllAccsRel, getDomain());
1254     isl_set *AllAccs = isl_map_range(AllAccsRel);
1255 
1256     for (MemoryAccess *MA : MemAccs) {
1257       if (MA == CandidatePair.first || MA == CandidatePair.second)
1258         continue;
1259 
1260       isl_map *AccRel =
1261           isl_map_intersect_domain(MA->getAccessRelation(), getDomain());
1262       isl_set *Accs = isl_map_range(AccRel);
1263 
1264       if (isl_set_has_equal_space(AllAccs, Accs) || isl_set_free(Accs)) {
1265         isl_set *OverlapAccs = isl_set_intersect(Accs, isl_set_copy(AllAccs));
1266         Valid = Valid && isl_set_is_empty(OverlapAccs);
1267         isl_set_free(OverlapAccs);
1268       }
1269     }
1270 
1271     isl_set_free(AllAccs);
1272     if (!Valid)
1273       continue;
1274 
1275     const LoadInst *Load =
1276         dyn_cast<const LoadInst>(CandidatePair.first->getAccessInstruction());
1277     MemoryAccess::ReductionType RT =
1278         getReductionType(dyn_cast<BinaryOperator>(Load->user_back()), Load);
1279 
1280     // If no overlapping access was found we mark the load and store as
1281     // reduction like.
1282     CandidatePair.first->markAsReductionLike(RT);
1283     CandidatePair.second->markAsReductionLike(RT);
1284   }
1285 }
1286 
1287 std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
1288 
1289 std::string ScopStmt::getScheduleStr() const {
1290   auto *S = getSchedule();
1291   auto Str = stringFromIslObj(S);
1292   isl_map_free(S);
1293   return Str;
1294 }
1295 
1296 unsigned ScopStmt::getNumParams() const { return Parent.getNumParams(); }
1297 
1298 unsigned ScopStmt::getNumIterators() const { return NestLoops.size(); }
1299 
1300 const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
1301 
1302 const Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
1303   return NestLoops[Dimension];
1304 }
1305 
1306 isl_ctx *ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
1307 
1308 __isl_give isl_set *ScopStmt::getDomain() const { return isl_set_copy(Domain); }
1309 
1310 __isl_give isl_space *ScopStmt::getDomainSpace() const {
1311   return isl_set_get_space(Domain);
1312 }
1313 
1314 __isl_give isl_id *ScopStmt::getDomainId() const {
1315   return isl_set_get_tuple_id(Domain);
1316 }
1317 
1318 ScopStmt::~ScopStmt() {
1319   DeleteContainerSeconds(InstructionToAccess);
1320   isl_set_free(Domain);
1321 }
1322 
1323 void ScopStmt::print(raw_ostream &OS) const {
1324   OS << "\t" << getBaseName() << "\n";
1325   OS.indent(12) << "Domain :=\n";
1326 
1327   if (Domain) {
1328     OS.indent(16) << getDomainStr() << ";\n";
1329   } else
1330     OS.indent(16) << "n/a\n";
1331 
1332   OS.indent(12) << "Schedule :=\n";
1333 
1334   if (Domain) {
1335     OS.indent(16) << getScheduleStr() << ";\n";
1336   } else
1337     OS.indent(16) << "n/a\n";
1338 
1339   for (MemoryAccess *Access : MemAccs)
1340     Access->print(OS);
1341 }
1342 
1343 void ScopStmt::dump() const { print(dbgs()); }
1344 
1345 void ScopStmt::hoistMemoryAccesses(MemoryAccessList &InvMAs,
1346                                    InvariantAccessesTy &TargetList) {
1347 
1348   // Remove all memory accesses in @p InvMAs from this statement together
1349   // with all scalar accesses that were caused by them. The tricky iteration
1350   // order uses is needed because the MemAccs is a vector and the order in
1351   // which the accesses of each memory access list (MAL) are stored in this
1352   // vector is reversed.
1353   for (MemoryAccess *MA : InvMAs) {
1354     auto &MAL = *lookupAccessesFor(MA->getAccessInstruction());
1355     MAL.reverse();
1356 
1357     auto MALIt = MAL.begin();
1358     auto MALEnd = MAL.end();
1359     auto MemAccsIt = MemAccs.begin();
1360     while (MALIt != MALEnd) {
1361       while (*MemAccsIt != *MALIt)
1362         MemAccsIt++;
1363 
1364       MALIt++;
1365       MemAccs.erase(MemAccsIt);
1366     }
1367 
1368     InstructionToAccess.erase(MA->getAccessInstruction());
1369     delete &MAL;
1370   }
1371 
1372   // Get the context under which this statement, hence the memory accesses, are
1373   // executed.
1374   isl_set *DomainCtx = isl_set_params(getDomain());
1375   DomainCtx = isl_set_remove_redundancies(DomainCtx);
1376   DomainCtx = isl_set_detect_equalities(DomainCtx);
1377   DomainCtx = isl_set_coalesce(DomainCtx);
1378 
1379   for (MemoryAccess *MA : InvMAs)
1380     TargetList.push_back(std::make_pair(MA, isl_set_copy(DomainCtx)));
1381 
1382   isl_set_free(DomainCtx);
1383 }
1384 
1385 //===----------------------------------------------------------------------===//
1386 /// Scop class implement
1387 
1388 void Scop::setContext(__isl_take isl_set *NewContext) {
1389   NewContext = isl_set_align_params(NewContext, isl_set_get_space(Context));
1390   isl_set_free(Context);
1391   Context = NewContext;
1392 }
1393 
1394 void Scop::addParams(std::vector<const SCEV *> NewParameters) {
1395   for (const SCEV *Parameter : NewParameters) {
1396     Parameter = extractConstantFactor(Parameter, *SE).second;
1397     if (ParameterIds.find(Parameter) != ParameterIds.end())
1398       continue;
1399 
1400     int dimension = Parameters.size();
1401 
1402     Parameters.push_back(Parameter);
1403     ParameterIds[Parameter] = dimension;
1404   }
1405 }
1406 
1407 __isl_give isl_id *Scop::getIdForParam(const SCEV *Parameter) const {
1408   ParamIdType::const_iterator IdIter = ParameterIds.find(Parameter);
1409 
1410   if (IdIter == ParameterIds.end())
1411     return nullptr;
1412 
1413   std::string ParameterName;
1414 
1415   if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
1416     Value *Val = ValueParameter->getValue();
1417     ParameterName = Val->getName();
1418   }
1419 
1420   if (ParameterName == "" || ParameterName.substr(0, 2) == "p_")
1421     ParameterName = "p_" + utostr_32(IdIter->second);
1422 
1423   return isl_id_alloc(getIslCtx(), ParameterName.c_str(),
1424                       const_cast<void *>((const void *)Parameter));
1425 }
1426 
1427 isl_set *Scop::addNonEmptyDomainConstraints(isl_set *C) const {
1428   isl_set *DomainContext = isl_union_set_params(getDomains());
1429   return isl_set_intersect_params(C, DomainContext);
1430 }
1431 
1432 void Scop::buildBoundaryContext() {
1433   BoundaryContext = Affinator.getWrappingContext();
1434   BoundaryContext = isl_set_complement(BoundaryContext);
1435   BoundaryContext = isl_set_gist_params(BoundaryContext, getContext());
1436 }
1437 
1438 void Scop::addUserContext() {
1439   if (UserContextStr.empty())
1440     return;
1441 
1442   isl_set *UserContext = isl_set_read_from_str(IslCtx, UserContextStr.c_str());
1443   isl_space *Space = getParamSpace();
1444   if (isl_space_dim(Space, isl_dim_param) !=
1445       isl_set_dim(UserContext, isl_dim_param)) {
1446     auto SpaceStr = isl_space_to_str(Space);
1447     errs() << "Error: the context provided in -polly-context has not the same "
1448            << "number of dimensions than the computed context. Due to this "
1449            << "mismatch, the -polly-context option is ignored. Please provide "
1450            << "the context in the parameter space: " << SpaceStr << ".\n";
1451     free(SpaceStr);
1452     isl_set_free(UserContext);
1453     isl_space_free(Space);
1454     return;
1455   }
1456 
1457   for (unsigned i = 0; i < isl_space_dim(Space, isl_dim_param); i++) {
1458     auto NameContext = isl_set_get_dim_name(Context, isl_dim_param, i);
1459     auto NameUserContext = isl_set_get_dim_name(UserContext, isl_dim_param, i);
1460 
1461     if (strcmp(NameContext, NameUserContext) != 0) {
1462       auto SpaceStr = isl_space_to_str(Space);
1463       errs() << "Error: the name of dimension " << i
1464              << " provided in -polly-context "
1465              << "is '" << NameUserContext << "', but the name in the computed "
1466              << "context is '" << NameContext
1467              << "'. Due to this name mismatch, "
1468              << "the -polly-context option is ignored. Please provide "
1469              << "the context in the parameter space: " << SpaceStr << ".\n";
1470       free(SpaceStr);
1471       isl_set_free(UserContext);
1472       isl_space_free(Space);
1473       return;
1474     }
1475 
1476     UserContext =
1477         isl_set_set_dim_id(UserContext, isl_dim_param, i,
1478                            isl_space_get_dim_id(Space, isl_dim_param, i));
1479   }
1480 
1481   Context = isl_set_intersect(Context, UserContext);
1482   isl_space_free(Space);
1483 }
1484 
1485 void Scop::buildContext() {
1486   isl_space *Space = isl_space_params_alloc(IslCtx, 0);
1487   Context = isl_set_universe(isl_space_copy(Space));
1488   AssumedContext = isl_set_universe(Space);
1489 }
1490 
1491 void Scop::addParameterBounds() {
1492   for (const auto &ParamID : ParameterIds) {
1493     int dim = ParamID.second;
1494 
1495     ConstantRange SRange = SE->getSignedRange(ParamID.first);
1496 
1497     Context = addRangeBoundsToSet(Context, SRange, dim, isl_dim_param);
1498   }
1499 }
1500 
1501 void Scop::realignParams() {
1502   // Add all parameters into a common model.
1503   isl_space *Space = isl_space_params_alloc(IslCtx, ParameterIds.size());
1504 
1505   for (const auto &ParamID : ParameterIds) {
1506     const SCEV *Parameter = ParamID.first;
1507     isl_id *id = getIdForParam(Parameter);
1508     Space = isl_space_set_dim_id(Space, isl_dim_param, ParamID.second, id);
1509   }
1510 
1511   // Align the parameters of all data structures to the model.
1512   Context = isl_set_align_params(Context, Space);
1513 
1514   for (ScopStmt &Stmt : *this)
1515     Stmt.realignParams();
1516 }
1517 
1518 static __isl_give isl_set *
1519 simplifyAssumptionContext(__isl_take isl_set *AssumptionContext,
1520                           const Scop &S) {
1521   isl_set *DomainParameters = isl_union_set_params(S.getDomains());
1522   AssumptionContext = isl_set_gist_params(AssumptionContext, DomainParameters);
1523   AssumptionContext = isl_set_gist_params(AssumptionContext, S.getContext());
1524   return AssumptionContext;
1525 }
1526 
1527 void Scop::simplifyContexts() {
1528   // The parameter constraints of the iteration domains give us a set of
1529   // constraints that need to hold for all cases where at least a single
1530   // statement iteration is executed in the whole scop. We now simplify the
1531   // assumed context under the assumption that such constraints hold and at
1532   // least a single statement iteration is executed. For cases where no
1533   // statement instances are executed, the assumptions we have taken about
1534   // the executed code do not matter and can be changed.
1535   //
1536   // WARNING: This only holds if the assumptions we have taken do not reduce
1537   //          the set of statement instances that are executed. Otherwise we
1538   //          may run into a case where the iteration domains suggest that
1539   //          for a certain set of parameter constraints no code is executed,
1540   //          but in the original program some computation would have been
1541   //          performed. In such a case, modifying the run-time conditions and
1542   //          possibly influencing the run-time check may cause certain scops
1543   //          to not be executed.
1544   //
1545   // Example:
1546   //
1547   //   When delinearizing the following code:
1548   //
1549   //     for (long i = 0; i < 100; i++)
1550   //       for (long j = 0; j < m; j++)
1551   //         A[i+p][j] = 1.0;
1552   //
1553   //   we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
1554   //   otherwise we would access out of bound data. Now, knowing that code is
1555   //   only executed for the case m >= 0, it is sufficient to assume p >= 0.
1556   AssumedContext = simplifyAssumptionContext(AssumedContext, *this);
1557   BoundaryContext = simplifyAssumptionContext(BoundaryContext, *this);
1558 }
1559 
1560 /// @brief Add the minimal/maximal access in @p Set to @p User.
1561 static isl_stat buildMinMaxAccess(__isl_take isl_set *Set, void *User) {
1562   Scop::MinMaxVectorTy *MinMaxAccesses = (Scop::MinMaxVectorTy *)User;
1563   isl_pw_multi_aff *MinPMA, *MaxPMA;
1564   isl_pw_aff *LastDimAff;
1565   isl_aff *OneAff;
1566   unsigned Pos;
1567 
1568   // Restrict the number of parameters involved in the access as the lexmin/
1569   // lexmax computation will take too long if this number is high.
1570   //
1571   // Experiments with a simple test case using an i7 4800MQ:
1572   //
1573   //  #Parameters involved | Time (in sec)
1574   //            6          |     0.01
1575   //            7          |     0.04
1576   //            8          |     0.12
1577   //            9          |     0.40
1578   //           10          |     1.54
1579   //           11          |     6.78
1580   //           12          |    30.38
1581   //
1582   if (isl_set_n_param(Set) > RunTimeChecksMaxParameters) {
1583     unsigned InvolvedParams = 0;
1584     for (unsigned u = 0, e = isl_set_n_param(Set); u < e; u++)
1585       if (isl_set_involves_dims(Set, isl_dim_param, u, 1))
1586         InvolvedParams++;
1587 
1588     if (InvolvedParams > RunTimeChecksMaxParameters) {
1589       isl_set_free(Set);
1590       return isl_stat_error;
1591     }
1592   }
1593 
1594   Set = isl_set_remove_divs(Set);
1595 
1596   MinPMA = isl_set_lexmin_pw_multi_aff(isl_set_copy(Set));
1597   MaxPMA = isl_set_lexmax_pw_multi_aff(isl_set_copy(Set));
1598 
1599   MinPMA = isl_pw_multi_aff_coalesce(MinPMA);
1600   MaxPMA = isl_pw_multi_aff_coalesce(MaxPMA);
1601 
1602   // Adjust the last dimension of the maximal access by one as we want to
1603   // enclose the accessed memory region by MinPMA and MaxPMA. The pointer
1604   // we test during code generation might now point after the end of the
1605   // allocated array but we will never dereference it anyway.
1606   assert(isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) &&
1607          "Assumed at least one output dimension");
1608   Pos = isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) - 1;
1609   LastDimAff = isl_pw_multi_aff_get_pw_aff(MaxPMA, Pos);
1610   OneAff = isl_aff_zero_on_domain(
1611       isl_local_space_from_space(isl_pw_aff_get_domain_space(LastDimAff)));
1612   OneAff = isl_aff_add_constant_si(OneAff, 1);
1613   LastDimAff = isl_pw_aff_add(LastDimAff, isl_pw_aff_from_aff(OneAff));
1614   MaxPMA = isl_pw_multi_aff_set_pw_aff(MaxPMA, Pos, LastDimAff);
1615 
1616   MinMaxAccesses->push_back(std::make_pair(MinPMA, MaxPMA));
1617 
1618   isl_set_free(Set);
1619   return isl_stat_ok;
1620 }
1621 
1622 static __isl_give isl_set *getAccessDomain(MemoryAccess *MA) {
1623   isl_set *Domain = MA->getStatement()->getDomain();
1624   Domain = isl_set_project_out(Domain, isl_dim_set, 0, isl_set_n_dim(Domain));
1625   return isl_set_reset_tuple_id(Domain);
1626 }
1627 
1628 /// @brief Wrapper function to calculate minimal/maximal accesses to each array.
1629 static bool calculateMinMaxAccess(__isl_take isl_union_map *Accesses,
1630                                   __isl_take isl_union_set *Domains,
1631                                   Scop::MinMaxVectorTy &MinMaxAccesses) {
1632 
1633   Accesses = isl_union_map_intersect_domain(Accesses, Domains);
1634   isl_union_set *Locations = isl_union_map_range(Accesses);
1635   Locations = isl_union_set_coalesce(Locations);
1636   Locations = isl_union_set_detect_equalities(Locations);
1637   bool Valid = (0 == isl_union_set_foreach_set(Locations, buildMinMaxAccess,
1638                                                &MinMaxAccesses));
1639   isl_union_set_free(Locations);
1640   return Valid;
1641 }
1642 
1643 /// @brief Helper to treat non-affine regions and basic blocks the same.
1644 ///
1645 ///{
1646 
1647 /// @brief Return the block that is the representing block for @p RN.
1648 static inline BasicBlock *getRegionNodeBasicBlock(RegionNode *RN) {
1649   return RN->isSubRegion() ? RN->getNodeAs<Region>()->getEntry()
1650                            : RN->getNodeAs<BasicBlock>();
1651 }
1652 
1653 /// @brief Return the @p idx'th block that is executed after @p RN.
1654 static inline BasicBlock *
1655 getRegionNodeSuccessor(RegionNode *RN, TerminatorInst *TI, unsigned idx) {
1656   if (RN->isSubRegion()) {
1657     assert(idx == 0);
1658     return RN->getNodeAs<Region>()->getExit();
1659   }
1660   return TI->getSuccessor(idx);
1661 }
1662 
1663 /// @brief Return the smallest loop surrounding @p RN.
1664 static inline Loop *getRegionNodeLoop(RegionNode *RN, LoopInfo &LI) {
1665   if (!RN->isSubRegion())
1666     return LI.getLoopFor(RN->getNodeAs<BasicBlock>());
1667 
1668   Region *NonAffineSubRegion = RN->getNodeAs<Region>();
1669   Loop *L = LI.getLoopFor(NonAffineSubRegion->getEntry());
1670   while (L && NonAffineSubRegion->contains(L))
1671     L = L->getParentLoop();
1672   return L;
1673 }
1674 
1675 static inline unsigned getNumBlocksInRegionNode(RegionNode *RN) {
1676   if (!RN->isSubRegion())
1677     return 1;
1678 
1679   unsigned NumBlocks = 0;
1680   Region *R = RN->getNodeAs<Region>();
1681   for (auto BB : R->blocks()) {
1682     (void)BB;
1683     NumBlocks++;
1684   }
1685   return NumBlocks;
1686 }
1687 
1688 static bool containsErrorBlock(RegionNode *RN) {
1689   if (!RN->isSubRegion())
1690     return isErrorBlock(*RN->getNodeAs<BasicBlock>());
1691   for (BasicBlock *BB : RN->getNodeAs<Region>()->blocks())
1692     if (isErrorBlock(*BB))
1693       return true;
1694   return false;
1695 }
1696 
1697 ///}
1698 
1699 static inline __isl_give isl_set *addDomainDimId(__isl_take isl_set *Domain,
1700                                                  unsigned Dim, Loop *L) {
1701   Domain = isl_set_lower_bound_si(Domain, isl_dim_set, Dim, -1);
1702   isl_id *DimId =
1703       isl_id_alloc(isl_set_get_ctx(Domain), nullptr, static_cast<void *>(L));
1704   return isl_set_set_dim_id(Domain, isl_dim_set, Dim, DimId);
1705 }
1706 
1707 isl_set *Scop::getDomainConditions(ScopStmt *Stmt) {
1708   BasicBlock *BB = Stmt->isBlockStmt() ? Stmt->getBasicBlock()
1709                                        : Stmt->getRegion()->getEntry();
1710   return getDomainConditions(BB);
1711 }
1712 
1713 isl_set *Scop::getDomainConditions(BasicBlock *BB) {
1714   assert(DomainMap.count(BB) && "Requested BB did not have a domain");
1715   return isl_set_copy(DomainMap[BB]);
1716 }
1717 
1718 void Scop::buildDomains(Region *R, LoopInfo &LI, DominatorTree &DT) {
1719 
1720   auto *EntryBB = R->getEntry();
1721   int LD = getRelativeLoopDepth(LI.getLoopFor(EntryBB));
1722   auto *S = isl_set_universe(isl_space_set_alloc(getIslCtx(), 0, LD + 1));
1723 
1724   Loop *L = LI.getLoopFor(EntryBB);
1725   while (LD-- >= 0) {
1726     S = addDomainDimId(S, LD + 1, L);
1727     L = L->getParentLoop();
1728   }
1729 
1730   DomainMap[EntryBB] = S;
1731 
1732   if (SD.isNonAffineSubRegion(R, R))
1733     return;
1734 
1735   buildDomainsWithBranchConstraints(R, LI, DT);
1736   propagateDomainConstraints(R, LI, DT);
1737 }
1738 
1739 void Scop::buildDomainsWithBranchConstraints(Region *R, LoopInfo &LI,
1740                                              DominatorTree &DT) {
1741   RegionInfo &RI = *R->getRegionInfo();
1742 
1743   // To create the domain for each block in R we iterate over all blocks and
1744   // subregions in R and propagate the conditions under which the current region
1745   // element is executed. To this end we iterate in reverse post order over R as
1746   // it ensures that we first visit all predecessors of a region node (either a
1747   // basic block or a subregion) before we visit the region node itself.
1748   // Initially, only the domain for the SCoP region entry block is set and from
1749   // there we propagate the current domain to all successors, however we add the
1750   // condition that the successor is actually executed next.
1751   // As we are only interested in non-loop carried constraints here we can
1752   // simply skip loop back edges.
1753 
1754   ReversePostOrderTraversal<Region *> RTraversal(R);
1755   for (auto *RN : RTraversal) {
1756 
1757     // Recurse for affine subregions but go on for basic blocks and non-affine
1758     // subregions.
1759     if (RN->isSubRegion()) {
1760       Region *SubRegion = RN->getNodeAs<Region>();
1761       if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) {
1762         buildDomainsWithBranchConstraints(SubRegion, LI, DT);
1763         continue;
1764       }
1765     }
1766 
1767     // Error blocks are assumed not to be executed. Therefor they are not
1768     // checked properly in the ScopDetection. Any attempt to generate control
1769     // conditions from them might result in a crash. However, this is only true
1770     // for the first step of the domain generation (this function) where we
1771     // push the control conditions of a block to the successors. In the second
1772     // step (propagateDomainConstraints) we only receive domain constraints from
1773     // the predecessors and can therefor look at the domain of a error block.
1774     // That allows us to generate the assumptions needed for them not to be
1775     // executed at runtime.
1776     if (containsErrorBlock(RN))
1777       continue;
1778 
1779     BasicBlock *BB = getRegionNodeBasicBlock(RN);
1780     TerminatorInst *TI = BB->getTerminator();
1781 
1782     isl_set *Domain = DomainMap.lookup(BB);
1783     if (!Domain) {
1784       DEBUG(dbgs() << "\tSkip: " << BB->getName()
1785                    << ", it is only reachable from error blocks.\n");
1786       continue;
1787     }
1788 
1789     DEBUG(dbgs() << "\tVisit: " << BB->getName() << " : " << Domain << "\n");
1790 
1791     Loop *BBLoop = getRegionNodeLoop(RN, LI);
1792     int BBLoopDepth = getRelativeLoopDepth(BBLoop);
1793 
1794     // Build the condition sets for the successor nodes of the current region
1795     // node. If it is a non-affine subregion we will always execute the single
1796     // exit node, hence the single entry node domain is the condition set. For
1797     // basic blocks we use the helper function buildConditionSets.
1798     SmallVector<isl_set *, 8> ConditionSets;
1799     if (RN->isSubRegion())
1800       ConditionSets.push_back(isl_set_copy(Domain));
1801     else
1802       buildConditionSets(*this, TI, BBLoop, Domain, ConditionSets);
1803 
1804     // Now iterate over the successors and set their initial domain based on
1805     // their condition set. We skip back edges here and have to be careful when
1806     // we leave a loop not to keep constraints over a dimension that doesn't
1807     // exist anymore.
1808     assert(RN->isSubRegion() || TI->getNumSuccessors() == ConditionSets.size());
1809     for (unsigned u = 0, e = ConditionSets.size(); u < e; u++) {
1810       isl_set *CondSet = ConditionSets[u];
1811       BasicBlock *SuccBB = getRegionNodeSuccessor(RN, TI, u);
1812 
1813       // Skip back edges.
1814       if (DT.dominates(SuccBB, BB)) {
1815         isl_set_free(CondSet);
1816         continue;
1817       }
1818 
1819       // Do not adjust the number of dimensions if we enter a boxed loop or are
1820       // in a non-affine subregion or if the surrounding loop stays the same.
1821       Loop *SuccBBLoop = LI.getLoopFor(SuccBB);
1822       Region *SuccRegion = RI.getRegionFor(SuccBB);
1823       if (SD.isNonAffineSubRegion(SuccRegion, &getRegion()))
1824         while (SuccBBLoop && SuccRegion->contains(SuccBBLoop))
1825           SuccBBLoop = SuccBBLoop->getParentLoop();
1826 
1827       if (BBLoop != SuccBBLoop) {
1828 
1829         // Check if the edge to SuccBB is a loop entry or exit edge. If so
1830         // adjust the dimensionality accordingly. Lastly, if we leave a loop
1831         // and enter a new one we need to drop the old constraints.
1832         int SuccBBLoopDepth = getRelativeLoopDepth(SuccBBLoop);
1833         unsigned LoopDepthDiff = std::abs(BBLoopDepth - SuccBBLoopDepth);
1834         if (BBLoopDepth > SuccBBLoopDepth) {
1835           CondSet = isl_set_project_out(CondSet, isl_dim_set,
1836                                         isl_set_n_dim(CondSet) - LoopDepthDiff,
1837                                         LoopDepthDiff);
1838         } else if (SuccBBLoopDepth > BBLoopDepth) {
1839           assert(LoopDepthDiff == 1);
1840           CondSet = isl_set_add_dims(CondSet, isl_dim_set, 1);
1841           CondSet = addDomainDimId(CondSet, SuccBBLoopDepth, SuccBBLoop);
1842         } else if (BBLoopDepth >= 0) {
1843           assert(LoopDepthDiff <= 1);
1844           CondSet = isl_set_project_out(CondSet, isl_dim_set, BBLoopDepth, 1);
1845           CondSet = isl_set_add_dims(CondSet, isl_dim_set, 1);
1846           CondSet = addDomainDimId(CondSet, SuccBBLoopDepth, SuccBBLoop);
1847         }
1848       }
1849 
1850       // Set the domain for the successor or merge it with an existing domain in
1851       // case there are multiple paths (without loop back edges) to the
1852       // successor block.
1853       isl_set *&SuccDomain = DomainMap[SuccBB];
1854       if (!SuccDomain)
1855         SuccDomain = CondSet;
1856       else
1857         SuccDomain = isl_set_union(SuccDomain, CondSet);
1858 
1859       SuccDomain = isl_set_coalesce(SuccDomain);
1860       DEBUG(dbgs() << "\tSet SuccBB: " << SuccBB->getName() << " : "
1861                    << SuccDomain << "\n");
1862     }
1863   }
1864 }
1865 
1866 /// @brief Return the domain for @p BB wrt @p DomainMap.
1867 ///
1868 /// This helper function will lookup @p BB in @p DomainMap but also handle the
1869 /// case where @p BB is contained in a non-affine subregion using the region
1870 /// tree obtained by @p RI.
1871 static __isl_give isl_set *
1872 getDomainForBlock(BasicBlock *BB, DenseMap<BasicBlock *, isl_set *> &DomainMap,
1873                   RegionInfo &RI) {
1874   auto DIt = DomainMap.find(BB);
1875   if (DIt != DomainMap.end())
1876     return isl_set_copy(DIt->getSecond());
1877 
1878   Region *R = RI.getRegionFor(BB);
1879   while (R->getEntry() == BB)
1880     R = R->getParent();
1881   return getDomainForBlock(R->getEntry(), DomainMap, RI);
1882 }
1883 
1884 void Scop::propagateDomainConstraints(Region *R, LoopInfo &LI,
1885                                       DominatorTree &DT) {
1886   // Iterate over the region R and propagate the domain constrains from the
1887   // predecessors to the current node. In contrast to the
1888   // buildDomainsWithBranchConstraints function, this one will pull the domain
1889   // information from the predecessors instead of pushing it to the successors.
1890   // Additionally, we assume the domains to be already present in the domain
1891   // map here. However, we iterate again in reverse post order so we know all
1892   // predecessors have been visited before a block or non-affine subregion is
1893   // visited.
1894 
1895   // The set of boxed loops (loops in non-affine subregions) for this SCoP.
1896   auto &BoxedLoops = *SD.getBoxedLoops(&getRegion());
1897 
1898   ReversePostOrderTraversal<Region *> RTraversal(R);
1899   for (auto *RN : RTraversal) {
1900 
1901     // Recurse for affine subregions but go on for basic blocks and non-affine
1902     // subregions.
1903     if (RN->isSubRegion()) {
1904       Region *SubRegion = RN->getNodeAs<Region>();
1905       if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) {
1906         propagateDomainConstraints(SubRegion, LI, DT);
1907         continue;
1908       }
1909     }
1910 
1911     // Get the domain for the current block and check if it was initialized or
1912     // not. The only way it was not is if this block is only reachable via error
1913     // blocks, thus will not be executed under the assumptions we make. Such
1914     // blocks have to be skipped as their predecessors might not have domains
1915     // either. It would not benefit us to compute the domain anyway, only the
1916     // domains of the error blocks that are reachable from non-error blocks
1917     // are needed to generate assumptions.
1918     BasicBlock *BB = getRegionNodeBasicBlock(RN);
1919     isl_set *&Domain = DomainMap[BB];
1920     if (!Domain) {
1921       DEBUG(dbgs() << "\tSkip: " << BB->getName()
1922                    << ", it is only reachable from error blocks.\n");
1923       DomainMap.erase(BB);
1924       continue;
1925     }
1926     DEBUG(dbgs() << "\tVisit: " << BB->getName() << " : " << Domain << "\n");
1927 
1928     Loop *BBLoop = getRegionNodeLoop(RN, LI);
1929     int BBLoopDepth = getRelativeLoopDepth(BBLoop);
1930 
1931     isl_set *PredDom = isl_set_empty(isl_set_get_space(Domain));
1932     for (auto *PredBB : predecessors(BB)) {
1933 
1934       // Skip backedges
1935       if (DT.dominates(BB, PredBB))
1936         continue;
1937 
1938       isl_set *PredBBDom = nullptr;
1939 
1940       // Handle the SCoP entry block with its outside predecessors.
1941       if (!getRegion().contains(PredBB))
1942         PredBBDom = isl_set_universe(isl_set_get_space(PredDom));
1943 
1944       if (!PredBBDom) {
1945         // Determine the loop depth of the predecessor and adjust its domain to
1946         // the domain of the current block. This can mean we have to:
1947         //  o) Drop a dimension if this block is the exit of a loop, not the
1948         //     header of a new loop and the predecessor was part of the loop.
1949         //  o) Add an unconstrainted new dimension if this block is the header
1950         //     of a loop and the predecessor is not part of it.
1951         //  o) Drop the information about the innermost loop dimension when the
1952         //     predecessor and the current block are surrounded by different
1953         //     loops in the same depth.
1954         PredBBDom = getDomainForBlock(PredBB, DomainMap, *R->getRegionInfo());
1955         Loop *PredBBLoop = LI.getLoopFor(PredBB);
1956         while (BoxedLoops.count(PredBBLoop))
1957           PredBBLoop = PredBBLoop->getParentLoop();
1958 
1959         int PredBBLoopDepth = getRelativeLoopDepth(PredBBLoop);
1960         unsigned LoopDepthDiff = std::abs(BBLoopDepth - PredBBLoopDepth);
1961         if (BBLoopDepth < PredBBLoopDepth)
1962           PredBBDom = isl_set_project_out(
1963               PredBBDom, isl_dim_set, isl_set_n_dim(PredBBDom) - LoopDepthDiff,
1964               LoopDepthDiff);
1965         else if (PredBBLoopDepth < BBLoopDepth) {
1966           assert(LoopDepthDiff == 1);
1967           PredBBDom = isl_set_add_dims(PredBBDom, isl_dim_set, 1);
1968         } else if (BBLoop != PredBBLoop && BBLoopDepth >= 0) {
1969           assert(LoopDepthDiff <= 1);
1970           PredBBDom = isl_set_drop_constraints_involving_dims(
1971               PredBBDom, isl_dim_set, BBLoopDepth, 1);
1972         }
1973       }
1974 
1975       PredDom = isl_set_union(PredDom, PredBBDom);
1976     }
1977 
1978     // Under the union of all predecessor conditions we can reach this block.
1979     Domain = isl_set_coalesce(isl_set_intersect(Domain, PredDom));
1980 
1981     if (BBLoop && BBLoop->getHeader() == BB && getRegion().contains(BBLoop))
1982       addLoopBoundsToHeaderDomain(BBLoop, LI);
1983 
1984     // Add assumptions for error blocks.
1985     if (containsErrorBlock(RN)) {
1986       IsOptimized = true;
1987       isl_set *DomPar = isl_set_params(isl_set_copy(Domain));
1988       addAssumption(isl_set_complement(DomPar));
1989     }
1990   }
1991 }
1992 
1993 /// @brief Create a map from SetSpace -> SetSpace where the dimensions @p Dim
1994 ///        is incremented by one and all other dimensions are equal, e.g.,
1995 ///             [i0, i1, i2, i3] -> [i0, i1, i2 + 1, i3]
1996 ///        if @p Dim is 2 and @p SetSpace has 4 dimensions.
1997 static __isl_give isl_map *
1998 createNextIterationMap(__isl_take isl_space *SetSpace, unsigned Dim) {
1999   auto *MapSpace = isl_space_map_from_set(SetSpace);
2000   auto *NextIterationMap = isl_map_universe(isl_space_copy(MapSpace));
2001   for (unsigned u = 0; u < isl_map_n_in(NextIterationMap); u++)
2002     if (u != Dim)
2003       NextIterationMap =
2004           isl_map_equate(NextIterationMap, isl_dim_in, u, isl_dim_out, u);
2005   auto *C = isl_constraint_alloc_equality(isl_local_space_from_space(MapSpace));
2006   C = isl_constraint_set_constant_si(C, 1);
2007   C = isl_constraint_set_coefficient_si(C, isl_dim_in, Dim, 1);
2008   C = isl_constraint_set_coefficient_si(C, isl_dim_out, Dim, -1);
2009   NextIterationMap = isl_map_add_constraint(NextIterationMap, C);
2010   return NextIterationMap;
2011 }
2012 
2013 void Scop::addLoopBoundsToHeaderDomain(Loop *L, LoopInfo &LI) {
2014   int LoopDepth = getRelativeLoopDepth(L);
2015   assert(LoopDepth >= 0 && "Loop in region should have at least depth one");
2016 
2017   BasicBlock *HeaderBB = L->getHeader();
2018   assert(DomainMap.count(HeaderBB));
2019   isl_set *&HeaderBBDom = DomainMap[HeaderBB];
2020 
2021   isl_map *NextIterationMap =
2022       createNextIterationMap(isl_set_get_space(HeaderBBDom), LoopDepth);
2023 
2024   isl_set *UnionBackedgeCondition =
2025       isl_set_empty(isl_set_get_space(HeaderBBDom));
2026 
2027   SmallVector<llvm::BasicBlock *, 4> LatchBlocks;
2028   L->getLoopLatches(LatchBlocks);
2029 
2030   for (BasicBlock *LatchBB : LatchBlocks) {
2031 
2032     // If the latch is only reachable via error statements we skip it.
2033     isl_set *LatchBBDom = DomainMap.lookup(LatchBB);
2034     if (!LatchBBDom)
2035       continue;
2036 
2037     isl_set *BackedgeCondition = nullptr;
2038 
2039     TerminatorInst *TI = LatchBB->getTerminator();
2040     BranchInst *BI = dyn_cast<BranchInst>(TI);
2041     if (BI && BI->isUnconditional())
2042       BackedgeCondition = isl_set_copy(LatchBBDom);
2043     else {
2044       SmallVector<isl_set *, 8> ConditionSets;
2045       int idx = BI->getSuccessor(0) != HeaderBB;
2046       buildConditionSets(*this, TI, L, LatchBBDom, ConditionSets);
2047 
2048       // Free the non back edge condition set as we do not need it.
2049       isl_set_free(ConditionSets[1 - idx]);
2050 
2051       BackedgeCondition = ConditionSets[idx];
2052     }
2053 
2054     int LatchLoopDepth = getRelativeLoopDepth(LI.getLoopFor(LatchBB));
2055     assert(LatchLoopDepth >= LoopDepth);
2056     BackedgeCondition =
2057         isl_set_project_out(BackedgeCondition, isl_dim_set, LoopDepth + 1,
2058                             LatchLoopDepth - LoopDepth);
2059     UnionBackedgeCondition =
2060         isl_set_union(UnionBackedgeCondition, BackedgeCondition);
2061   }
2062 
2063   isl_map *ForwardMap = isl_map_lex_le(isl_set_get_space(HeaderBBDom));
2064   for (int i = 0; i < LoopDepth; i++)
2065     ForwardMap = isl_map_equate(ForwardMap, isl_dim_in, i, isl_dim_out, i);
2066 
2067   isl_set *UnionBackedgeConditionComplement =
2068       isl_set_complement(UnionBackedgeCondition);
2069   UnionBackedgeConditionComplement = isl_set_lower_bound_si(
2070       UnionBackedgeConditionComplement, isl_dim_set, LoopDepth, 0);
2071   UnionBackedgeConditionComplement =
2072       isl_set_apply(UnionBackedgeConditionComplement, ForwardMap);
2073   HeaderBBDom = isl_set_subtract(HeaderBBDom, UnionBackedgeConditionComplement);
2074   HeaderBBDom = isl_set_apply(HeaderBBDom, NextIterationMap);
2075 
2076   auto Parts = partitionSetParts(HeaderBBDom, LoopDepth);
2077   HeaderBBDom = Parts.second;
2078 
2079   // Check if there is a <nsw> tagged AddRec for this loop and if so do not add
2080   // the bounded assumptions to the context as they are already implied by the
2081   // <nsw> tag.
2082   if (Affinator.hasNSWAddRecForLoop(L)) {
2083     isl_set_free(Parts.first);
2084     return;
2085   }
2086 
2087   isl_set *UnboundedCtx = isl_set_params(Parts.first);
2088   isl_set *BoundedCtx = isl_set_complement(UnboundedCtx);
2089   addAssumption(BoundedCtx);
2090 }
2091 
2092 void Scop::buildAliasChecks(AliasAnalysis &AA) {
2093   if (!PollyUseRuntimeAliasChecks)
2094     return;
2095 
2096   if (buildAliasGroups(AA))
2097     return;
2098 
2099   // If a problem occurs while building the alias groups we need to delete
2100   // this SCoP and pretend it wasn't valid in the first place. To this end
2101   // we make the assumed context infeasible.
2102   addAssumption(isl_set_empty(getParamSpace()));
2103 
2104   DEBUG(dbgs() << "\n\nNOTE: Run time checks for " << getNameStr()
2105                << " could not be created as the number of parameters involved "
2106                   "is too high. The SCoP will be "
2107                   "dismissed.\nUse:\n\t--polly-rtc-max-parameters=X\nto adjust "
2108                   "the maximal number of parameters but be advised that the "
2109                   "compile time might increase exponentially.\n\n");
2110 }
2111 
2112 bool Scop::buildAliasGroups(AliasAnalysis &AA) {
2113   // To create sound alias checks we perform the following steps:
2114   //   o) Use the alias analysis and an alias set tracker to build alias sets
2115   //      for all memory accesses inside the SCoP.
2116   //   o) For each alias set we then map the aliasing pointers back to the
2117   //      memory accesses we know, thus obtain groups of memory accesses which
2118   //      might alias.
2119   //   o) We divide each group based on the domains of the minimal/maximal
2120   //      accesses. That means two minimal/maximal accesses are only in a group
2121   //      if their access domains intersect, otherwise they are in different
2122   //      ones.
2123   //   o) We partition each group into read only and non read only accesses.
2124   //   o) For each group with more than one base pointer we then compute minimal
2125   //      and maximal accesses to each array of a group in read only and non
2126   //      read only partitions separately.
2127   using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
2128 
2129   AliasSetTracker AST(AA);
2130 
2131   DenseMap<Value *, MemoryAccess *> PtrToAcc;
2132   DenseSet<Value *> HasWriteAccess;
2133   for (ScopStmt &Stmt : *this) {
2134 
2135     // Skip statements with an empty domain as they will never be executed.
2136     isl_set *StmtDomain = Stmt.getDomain();
2137     bool StmtDomainEmpty = isl_set_is_empty(StmtDomain);
2138     isl_set_free(StmtDomain);
2139     if (StmtDomainEmpty)
2140       continue;
2141 
2142     for (MemoryAccess *MA : Stmt) {
2143       if (MA->isImplicit())
2144         continue;
2145       if (!MA->isRead())
2146         HasWriteAccess.insert(MA->getBaseAddr());
2147       Instruction *Acc = MA->getAccessInstruction();
2148       PtrToAcc[getPointerOperand(*Acc)] = MA;
2149       AST.add(Acc);
2150     }
2151   }
2152 
2153   SmallVector<AliasGroupTy, 4> AliasGroups;
2154   for (AliasSet &AS : AST) {
2155     if (AS.isMustAlias() || AS.isForwardingAliasSet())
2156       continue;
2157     AliasGroupTy AG;
2158     for (auto PR : AS)
2159       AG.push_back(PtrToAcc[PR.getValue()]);
2160     assert(AG.size() > 1 &&
2161            "Alias groups should contain at least two accesses");
2162     AliasGroups.push_back(std::move(AG));
2163   }
2164 
2165   // Split the alias groups based on their domain.
2166   for (unsigned u = 0; u < AliasGroups.size(); u++) {
2167     AliasGroupTy NewAG;
2168     AliasGroupTy &AG = AliasGroups[u];
2169     AliasGroupTy::iterator AGI = AG.begin();
2170     isl_set *AGDomain = getAccessDomain(*AGI);
2171     while (AGI != AG.end()) {
2172       MemoryAccess *MA = *AGI;
2173       isl_set *MADomain = getAccessDomain(MA);
2174       if (isl_set_is_disjoint(AGDomain, MADomain)) {
2175         NewAG.push_back(MA);
2176         AGI = AG.erase(AGI);
2177         isl_set_free(MADomain);
2178       } else {
2179         AGDomain = isl_set_union(AGDomain, MADomain);
2180         AGI++;
2181       }
2182     }
2183     if (NewAG.size() > 1)
2184       AliasGroups.push_back(std::move(NewAG));
2185     isl_set_free(AGDomain);
2186   }
2187 
2188   MapVector<const Value *, SmallPtrSet<MemoryAccess *, 8>> ReadOnlyPairs;
2189   SmallPtrSet<const Value *, 4> NonReadOnlyBaseValues;
2190   for (AliasGroupTy &AG : AliasGroups) {
2191     NonReadOnlyBaseValues.clear();
2192     ReadOnlyPairs.clear();
2193 
2194     if (AG.size() < 2) {
2195       AG.clear();
2196       continue;
2197     }
2198 
2199     for (auto II = AG.begin(); II != AG.end();) {
2200       Value *BaseAddr = (*II)->getBaseAddr();
2201       if (HasWriteAccess.count(BaseAddr)) {
2202         NonReadOnlyBaseValues.insert(BaseAddr);
2203         II++;
2204       } else {
2205         ReadOnlyPairs[BaseAddr].insert(*II);
2206         II = AG.erase(II);
2207       }
2208     }
2209 
2210     // If we don't have read only pointers check if there are at least two
2211     // non read only pointers, otherwise clear the alias group.
2212     if (ReadOnlyPairs.empty() && NonReadOnlyBaseValues.size() <= 1) {
2213       AG.clear();
2214       continue;
2215     }
2216 
2217     // If we don't have non read only pointers clear the alias group.
2218     if (NonReadOnlyBaseValues.empty()) {
2219       AG.clear();
2220       continue;
2221     }
2222 
2223     // Calculate minimal and maximal accesses for non read only accesses.
2224     MinMaxAliasGroups.emplace_back();
2225     MinMaxVectorPairTy &pair = MinMaxAliasGroups.back();
2226     MinMaxVectorTy &MinMaxAccessesNonReadOnly = pair.first;
2227     MinMaxVectorTy &MinMaxAccessesReadOnly = pair.second;
2228     MinMaxAccessesNonReadOnly.reserve(AG.size());
2229 
2230     isl_union_map *Accesses = isl_union_map_empty(getParamSpace());
2231 
2232     // AG contains only non read only accesses.
2233     for (MemoryAccess *MA : AG)
2234       Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation());
2235 
2236     bool Valid = calculateMinMaxAccess(Accesses, getDomains(),
2237                                        MinMaxAccessesNonReadOnly);
2238 
2239     // Bail out if the number of values we need to compare is too large.
2240     // This is important as the number of comparisions grows quadratically with
2241     // the number of values we need to compare.
2242     if (!Valid || (MinMaxAccessesNonReadOnly.size() + !ReadOnlyPairs.empty() >
2243                    RunTimeChecksMaxArraysPerGroup))
2244       return false;
2245 
2246     // Calculate minimal and maximal accesses for read only accesses.
2247     MinMaxAccessesReadOnly.reserve(ReadOnlyPairs.size());
2248     Accesses = isl_union_map_empty(getParamSpace());
2249 
2250     for (const auto &ReadOnlyPair : ReadOnlyPairs)
2251       for (MemoryAccess *MA : ReadOnlyPair.second)
2252         Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation());
2253 
2254     Valid =
2255         calculateMinMaxAccess(Accesses, getDomains(), MinMaxAccessesReadOnly);
2256 
2257     if (!Valid)
2258       return false;
2259   }
2260 
2261   return true;
2262 }
2263 
2264 static Loop *getLoopSurroundingRegion(Region &R, LoopInfo &LI) {
2265   Loop *L = LI.getLoopFor(R.getEntry());
2266   return L ? (R.contains(L) ? L->getParentLoop() : L) : nullptr;
2267 }
2268 
2269 static unsigned getMaxLoopDepthInRegion(const Region &R, LoopInfo &LI,
2270                                         ScopDetection &SD) {
2271 
2272   const ScopDetection::BoxedLoopsSetTy *BoxedLoops = SD.getBoxedLoops(&R);
2273 
2274   unsigned MinLD = INT_MAX, MaxLD = 0;
2275   for (BasicBlock *BB : R.blocks()) {
2276     if (Loop *L = LI.getLoopFor(BB)) {
2277       if (!R.contains(L))
2278         continue;
2279       if (BoxedLoops && BoxedLoops->count(L))
2280         continue;
2281       unsigned LD = L->getLoopDepth();
2282       MinLD = std::min(MinLD, LD);
2283       MaxLD = std::max(MaxLD, LD);
2284     }
2285   }
2286 
2287   // Handle the case that there is no loop in the SCoP first.
2288   if (MaxLD == 0)
2289     return 1;
2290 
2291   assert(MinLD >= 1 && "Minimal loop depth should be at least one");
2292   assert(MaxLD >= MinLD &&
2293          "Maximal loop depth was smaller than mininaml loop depth?");
2294   return MaxLD - MinLD + 1;
2295 }
2296 
2297 Scop::Scop(Region &R, AccFuncMapType &AccFuncMap, ScopDetection &SD,
2298            ScalarEvolution &ScalarEvolution, DominatorTree &DT,
2299            isl_ctx *Context, unsigned MaxLoopDepth)
2300     : DT(DT), SE(&ScalarEvolution), SD(SD), R(R), AccFuncMap(AccFuncMap),
2301       IsOptimized(false), HasSingleExitEdge(R.getExitingBlock()),
2302       MaxLoopDepth(MaxLoopDepth), IslCtx(Context), Context(nullptr),
2303       Affinator(this), AssumedContext(nullptr), BoundaryContext(nullptr),
2304       Schedule(nullptr) {}
2305 
2306 void Scop::init(LoopInfo &LI, AliasAnalysis &AA) {
2307   buildContext();
2308   buildDomains(&R, LI, DT);
2309 
2310   // Remove empty and ignored statements.
2311   // Exit early in case there are no executable statements left in this scop.
2312   simplifySCoP(true);
2313   if (Stmts.empty())
2314     return;
2315 
2316   // The ScopStmts now have enough information to initialize themselves.
2317   for (ScopStmt &Stmt : Stmts)
2318     Stmt.init();
2319 
2320   DenseMap<Loop *, std::pair<isl_schedule *, unsigned>> LoopSchedules;
2321   Loop *L = getLoopSurroundingRegion(R, LI);
2322   LoopSchedules[L];
2323   buildSchedule(&R, LI, LoopSchedules);
2324   updateAccessDimensionality();
2325   Schedule = LoopSchedules[L].first;
2326 
2327   realignParams();
2328   addParameterBounds();
2329   addUserContext();
2330   buildBoundaryContext();
2331   simplifyContexts();
2332   buildAliasChecks(AA);
2333 
2334   hoistInvariantLoads();
2335   simplifySCoP(false);
2336 }
2337 
2338 Scop::~Scop() {
2339   isl_set_free(Context);
2340   isl_set_free(AssumedContext);
2341   isl_set_free(BoundaryContext);
2342   isl_schedule_free(Schedule);
2343 
2344   for (auto It : DomainMap)
2345     isl_set_free(It.second);
2346 
2347   // Free the alias groups
2348   for (MinMaxVectorPairTy &MinMaxAccessPair : MinMaxAliasGroups) {
2349     for (MinMaxAccessTy &MMA : MinMaxAccessPair.first) {
2350       isl_pw_multi_aff_free(MMA.first);
2351       isl_pw_multi_aff_free(MMA.second);
2352     }
2353     for (MinMaxAccessTy &MMA : MinMaxAccessPair.second) {
2354       isl_pw_multi_aff_free(MMA.first);
2355       isl_pw_multi_aff_free(MMA.second);
2356     }
2357   }
2358 
2359   for (const auto &IA : InvariantAccesses)
2360     isl_set_free(IA.second);
2361 }
2362 
2363 void Scop::updateAccessDimensionality() {
2364   for (auto &Stmt : *this)
2365     for (auto &Access : Stmt)
2366       Access->updateDimensionality();
2367 }
2368 
2369 void Scop::simplifySCoP(bool RemoveIgnoredStmts) {
2370   for (auto StmtIt = Stmts.begin(), StmtEnd = Stmts.end(); StmtIt != StmtEnd;) {
2371     ScopStmt &Stmt = *StmtIt;
2372     RegionNode *RN = Stmt.isRegionStmt()
2373                          ? Stmt.getRegion()->getNode()
2374                          : getRegion().getBBNode(Stmt.getBasicBlock());
2375 
2376     if (StmtIt->isEmpty() ||
2377         isl_set_is_empty(DomainMap[getRegionNodeBasicBlock(RN)]) ||
2378         (RemoveIgnoredStmts && isIgnored(RN))) {
2379 
2380       // Remove the statement because it is unnecessary.
2381       if (Stmt.isRegionStmt())
2382         for (BasicBlock *BB : Stmt.getRegion()->blocks())
2383           StmtMap.erase(BB);
2384       else
2385         StmtMap.erase(Stmt.getBasicBlock());
2386 
2387       StmtIt = Stmts.erase(StmtIt);
2388       continue;
2389     }
2390 
2391     StmtIt++;
2392   }
2393 }
2394 
2395 void Scop::hoistInvariantLoads() {
2396   isl_union_map *Writes = getWrites();
2397   for (ScopStmt &Stmt : *this) {
2398 
2399     // TODO: Loads that are not loop carried, hence are in a statement with
2400     //       zero iterators, are by construction invariant, though we
2401     //       currently "hoist" them anyway.
2402 
2403     BasicBlock *BB = Stmt.isBlockStmt() ? Stmt.getBasicBlock()
2404                                         : Stmt.getRegion()->getEntry();
2405     isl_set *Domain = Stmt.getDomain();
2406     MemoryAccessList InvMAs;
2407 
2408     for (MemoryAccess *MA : Stmt) {
2409       if (MA->isImplicit() || MA->isWrite() || !MA->isAffine())
2410         continue;
2411 
2412       // Skip accesses in non-affine subregions as they might not be executed
2413       // under the same condition as the entry of the non-affine subregion.
2414       if (BB != MA->getAccessInstruction()->getParent())
2415         continue;
2416 
2417       isl_map *AccessRelation = MA->getAccessRelation();
2418       if (isl_map_involves_dims(AccessRelation, isl_dim_in, 0,
2419                                 Stmt.getNumIterators())) {
2420         isl_map_free(AccessRelation);
2421         continue;
2422       }
2423 
2424       AccessRelation =
2425           isl_map_intersect_domain(AccessRelation, isl_set_copy(Domain));
2426       isl_set *AccessRange = isl_map_range(AccessRelation);
2427 
2428       isl_union_map *Written = isl_union_map_intersect_range(
2429           isl_union_map_copy(Writes), isl_union_set_from_set(AccessRange));
2430       bool IsWritten = !isl_union_map_is_empty(Written);
2431       isl_union_map_free(Written);
2432 
2433       if (IsWritten)
2434         continue;
2435 
2436       InvMAs.push_front(MA);
2437     }
2438 
2439     // We inserted invariant accesses always in the front but need them to be
2440     // sorted in a "natural order". The statements are already sorted in reverse
2441     // post order and that suffices for the accesses too. The reason we require
2442     // an order in the first place is the dependences between invariant loads
2443     // that can be caused by indirect loads.
2444     InvMAs.reverse();
2445 
2446     // Transfer the memory access from the statement to the SCoP.
2447     Stmt.hoistMemoryAccesses(InvMAs, InvariantAccesses);
2448 
2449     isl_set_free(Domain);
2450   }
2451   isl_union_map_free(Writes);
2452 
2453   if (!InvariantAccesses.empty())
2454     IsOptimized = true;
2455 }
2456 
2457 const ScopArrayInfo *
2458 Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType,
2459                                ArrayRef<const SCEV *> Sizes, bool IsPHI) {
2460   auto &SAI = ScopArrayInfoMap[std::make_pair(BasePtr, IsPHI)];
2461   if (!SAI) {
2462     SAI.reset(new ScopArrayInfo(BasePtr, AccessType, getIslCtx(), Sizes, IsPHI,
2463                                 this));
2464   } else {
2465     if (Sizes.size() > SAI->getNumberOfDimensions())
2466       SAI->updateSizes(Sizes);
2467   }
2468   return SAI.get();
2469 }
2470 
2471 const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, bool IsPHI) {
2472   auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, IsPHI)].get();
2473   assert(SAI && "No ScopArrayInfo available for this base pointer");
2474   return SAI;
2475 }
2476 
2477 std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
2478 std::string Scop::getAssumedContextStr() const {
2479   return stringFromIslObj(AssumedContext);
2480 }
2481 std::string Scop::getBoundaryContextStr() const {
2482   return stringFromIslObj(BoundaryContext);
2483 }
2484 
2485 std::string Scop::getNameStr() const {
2486   std::string ExitName, EntryName;
2487   raw_string_ostream ExitStr(ExitName);
2488   raw_string_ostream EntryStr(EntryName);
2489 
2490   R.getEntry()->printAsOperand(EntryStr, false);
2491   EntryStr.str();
2492 
2493   if (R.getExit()) {
2494     R.getExit()->printAsOperand(ExitStr, false);
2495     ExitStr.str();
2496   } else
2497     ExitName = "FunctionExit";
2498 
2499   return EntryName + "---" + ExitName;
2500 }
2501 
2502 __isl_give isl_set *Scop::getContext() const { return isl_set_copy(Context); }
2503 __isl_give isl_space *Scop::getParamSpace() const {
2504   return isl_set_get_space(Context);
2505 }
2506 
2507 __isl_give isl_set *Scop::getAssumedContext() const {
2508   return isl_set_copy(AssumedContext);
2509 }
2510 
2511 __isl_give isl_set *Scop::getRuntimeCheckContext() const {
2512   isl_set *RuntimeCheckContext = getAssumedContext();
2513   RuntimeCheckContext =
2514       isl_set_intersect(RuntimeCheckContext, getBoundaryContext());
2515   RuntimeCheckContext = simplifyAssumptionContext(RuntimeCheckContext, *this);
2516   return RuntimeCheckContext;
2517 }
2518 
2519 bool Scop::hasFeasibleRuntimeContext() const {
2520   isl_set *RuntimeCheckContext = getRuntimeCheckContext();
2521   RuntimeCheckContext = addNonEmptyDomainConstraints(RuntimeCheckContext);
2522   bool IsFeasible = !isl_set_is_empty(RuntimeCheckContext);
2523   isl_set_free(RuntimeCheckContext);
2524   return IsFeasible;
2525 }
2526 
2527 void Scop::addAssumption(__isl_take isl_set *Set) {
2528   AssumedContext = isl_set_intersect(AssumedContext, Set);
2529   AssumedContext = isl_set_coalesce(AssumedContext);
2530 }
2531 
2532 __isl_give isl_set *Scop::getBoundaryContext() const {
2533   return isl_set_copy(BoundaryContext);
2534 }
2535 
2536 void Scop::printContext(raw_ostream &OS) const {
2537   OS << "Context:\n";
2538 
2539   if (!Context) {
2540     OS.indent(4) << "n/a\n\n";
2541     return;
2542   }
2543 
2544   OS.indent(4) << getContextStr() << "\n";
2545 
2546   OS.indent(4) << "Assumed Context:\n";
2547   if (!AssumedContext) {
2548     OS.indent(4) << "n/a\n\n";
2549     return;
2550   }
2551 
2552   OS.indent(4) << getAssumedContextStr() << "\n";
2553 
2554   OS.indent(4) << "Boundary Context:\n";
2555   if (!BoundaryContext) {
2556     OS.indent(4) << "n/a\n\n";
2557     return;
2558   }
2559 
2560   OS.indent(4) << getBoundaryContextStr() << "\n";
2561 
2562   for (const SCEV *Parameter : Parameters) {
2563     int Dim = ParameterIds.find(Parameter)->second;
2564     OS.indent(4) << "p" << Dim << ": " << *Parameter << "\n";
2565   }
2566 }
2567 
2568 void Scop::printAliasAssumptions(raw_ostream &OS) const {
2569   int noOfGroups = 0;
2570   for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
2571     if (Pair.second.size() == 0)
2572       noOfGroups += 1;
2573     else
2574       noOfGroups += Pair.second.size();
2575   }
2576 
2577   OS.indent(4) << "Alias Groups (" << noOfGroups << "):\n";
2578   if (MinMaxAliasGroups.empty()) {
2579     OS.indent(8) << "n/a\n";
2580     return;
2581   }
2582 
2583   for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
2584 
2585     // If the group has no read only accesses print the write accesses.
2586     if (Pair.second.empty()) {
2587       OS.indent(8) << "[[";
2588       for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
2589         OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
2590            << ">";
2591       }
2592       OS << " ]]\n";
2593     }
2594 
2595     for (const MinMaxAccessTy &MMAReadOnly : Pair.second) {
2596       OS.indent(8) << "[[";
2597       OS << " <" << MMAReadOnly.first << ", " << MMAReadOnly.second << ">";
2598       for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
2599         OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
2600            << ">";
2601       }
2602       OS << " ]]\n";
2603     }
2604   }
2605 }
2606 
2607 void Scop::printStatements(raw_ostream &OS) const {
2608   OS << "Statements {\n";
2609 
2610   for (const ScopStmt &Stmt : *this)
2611     OS.indent(4) << Stmt;
2612 
2613   OS.indent(4) << "}\n";
2614 }
2615 
2616 void Scop::printArrayInfo(raw_ostream &OS) const {
2617   OS << "Arrays {\n";
2618 
2619   for (auto &Array : arrays())
2620     Array.second->print(OS);
2621 
2622   OS.indent(4) << "}\n";
2623 
2624   OS.indent(4) << "Arrays (Bounds as pw_affs) {\n";
2625 
2626   for (auto &Array : arrays())
2627     Array.second->print(OS, /* SizeAsPwAff */ true);
2628 
2629   OS.indent(4) << "}\n";
2630 }
2631 
2632 void Scop::print(raw_ostream &OS) const {
2633   OS.indent(4) << "Function: " << getRegion().getEntry()->getParent()->getName()
2634                << "\n";
2635   OS.indent(4) << "Region: " << getNameStr() << "\n";
2636   OS.indent(4) << "Max Loop Depth:  " << getMaxLoopDepth() << "\n";
2637   OS.indent(4) << "Invariant Accesses: {\n";
2638   for (const auto &IA : InvariantAccesses) {
2639     IA.first->print(OS);
2640     OS.indent(12) << "Execution Context: " << IA.second << "\n";
2641   }
2642   OS.indent(4) << "}\n";
2643   printContext(OS.indent(4));
2644   printArrayInfo(OS.indent(4));
2645   printAliasAssumptions(OS);
2646   printStatements(OS.indent(4));
2647 }
2648 
2649 void Scop::dump() const { print(dbgs()); }
2650 
2651 isl_ctx *Scop::getIslCtx() const { return IslCtx; }
2652 
2653 __isl_give isl_pw_aff *Scop::getPwAff(const SCEV *E, BasicBlock *BB) {
2654   return Affinator.getPwAff(E, BB);
2655 }
2656 
2657 __isl_give isl_union_set *Scop::getDomains() const {
2658   isl_union_set *Domain = isl_union_set_empty(getParamSpace());
2659 
2660   for (const ScopStmt &Stmt : *this)
2661     Domain = isl_union_set_add_set(Domain, Stmt.getDomain());
2662 
2663   return Domain;
2664 }
2665 
2666 __isl_give isl_union_map *Scop::getMustWrites() {
2667   isl_union_map *Write = isl_union_map_empty(getParamSpace());
2668 
2669   for (ScopStmt &Stmt : *this) {
2670     for (MemoryAccess *MA : Stmt) {
2671       if (!MA->isMustWrite())
2672         continue;
2673 
2674       isl_set *Domain = Stmt.getDomain();
2675       isl_map *AccessDomain = MA->getAccessRelation();
2676       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
2677       Write = isl_union_map_add_map(Write, AccessDomain);
2678     }
2679   }
2680   return isl_union_map_coalesce(Write);
2681 }
2682 
2683 __isl_give isl_union_map *Scop::getMayWrites() {
2684   isl_union_map *Write = isl_union_map_empty(getParamSpace());
2685 
2686   for (ScopStmt &Stmt : *this) {
2687     for (MemoryAccess *MA : Stmt) {
2688       if (!MA->isMayWrite())
2689         continue;
2690 
2691       isl_set *Domain = Stmt.getDomain();
2692       isl_map *AccessDomain = MA->getAccessRelation();
2693       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
2694       Write = isl_union_map_add_map(Write, AccessDomain);
2695     }
2696   }
2697   return isl_union_map_coalesce(Write);
2698 }
2699 
2700 __isl_give isl_union_map *Scop::getWrites() {
2701   isl_union_map *Write = isl_union_map_empty(getParamSpace());
2702 
2703   for (ScopStmt &Stmt : *this) {
2704     for (MemoryAccess *MA : Stmt) {
2705       if (!MA->isWrite())
2706         continue;
2707 
2708       isl_set *Domain = Stmt.getDomain();
2709       isl_map *AccessDomain = MA->getAccessRelation();
2710       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
2711       Write = isl_union_map_add_map(Write, AccessDomain);
2712     }
2713   }
2714   return isl_union_map_coalesce(Write);
2715 }
2716 
2717 __isl_give isl_union_map *Scop::getReads() {
2718   isl_union_map *Read = isl_union_map_empty(getParamSpace());
2719 
2720   for (ScopStmt &Stmt : *this) {
2721     for (MemoryAccess *MA : Stmt) {
2722       if (!MA->isRead())
2723         continue;
2724 
2725       isl_set *Domain = Stmt.getDomain();
2726       isl_map *AccessDomain = MA->getAccessRelation();
2727 
2728       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
2729       Read = isl_union_map_add_map(Read, AccessDomain);
2730     }
2731   }
2732   return isl_union_map_coalesce(Read);
2733 }
2734 
2735 __isl_give isl_union_map *Scop::getSchedule() const {
2736   auto Tree = getScheduleTree();
2737   auto S = isl_schedule_get_map(Tree);
2738   isl_schedule_free(Tree);
2739   return S;
2740 }
2741 
2742 __isl_give isl_schedule *Scop::getScheduleTree() const {
2743   return isl_schedule_intersect_domain(isl_schedule_copy(Schedule),
2744                                        getDomains());
2745 }
2746 
2747 void Scop::setSchedule(__isl_take isl_union_map *NewSchedule) {
2748   auto *S = isl_schedule_from_domain(getDomains());
2749   S = isl_schedule_insert_partial_schedule(
2750       S, isl_multi_union_pw_aff_from_union_map(NewSchedule));
2751   isl_schedule_free(Schedule);
2752   Schedule = S;
2753 }
2754 
2755 void Scop::setScheduleTree(__isl_take isl_schedule *NewSchedule) {
2756   isl_schedule_free(Schedule);
2757   Schedule = NewSchedule;
2758 }
2759 
2760 bool Scop::restrictDomains(__isl_take isl_union_set *Domain) {
2761   bool Changed = false;
2762   for (ScopStmt &Stmt : *this) {
2763     isl_union_set *StmtDomain = isl_union_set_from_set(Stmt.getDomain());
2764     isl_union_set *NewStmtDomain = isl_union_set_intersect(
2765         isl_union_set_copy(StmtDomain), isl_union_set_copy(Domain));
2766 
2767     if (isl_union_set_is_subset(StmtDomain, NewStmtDomain)) {
2768       isl_union_set_free(StmtDomain);
2769       isl_union_set_free(NewStmtDomain);
2770       continue;
2771     }
2772 
2773     Changed = true;
2774 
2775     isl_union_set_free(StmtDomain);
2776     NewStmtDomain = isl_union_set_coalesce(NewStmtDomain);
2777 
2778     if (isl_union_set_is_empty(NewStmtDomain)) {
2779       Stmt.restrictDomain(isl_set_empty(Stmt.getDomainSpace()));
2780       isl_union_set_free(NewStmtDomain);
2781     } else
2782       Stmt.restrictDomain(isl_set_from_union_set(NewStmtDomain));
2783   }
2784   isl_union_set_free(Domain);
2785   return Changed;
2786 }
2787 
2788 ScalarEvolution *Scop::getSE() const { return SE; }
2789 
2790 bool Scop::isIgnored(RegionNode *RN) {
2791   BasicBlock *BB = getRegionNodeBasicBlock(RN);
2792 
2793   // Check if there are accesses contained.
2794   bool ContainsAccesses = false;
2795   if (!RN->isSubRegion())
2796     ContainsAccesses = getAccessFunctions(BB);
2797   else
2798     for (BasicBlock *RBB : RN->getNodeAs<Region>()->blocks())
2799       ContainsAccesses |= (getAccessFunctions(RBB) != nullptr);
2800   if (!ContainsAccesses)
2801     return true;
2802 
2803   // Check for reachability via non-error blocks.
2804   if (!DomainMap.count(BB))
2805     return true;
2806 
2807   // Check if error blocks are contained.
2808   if (containsErrorBlock(RN))
2809     return true;
2810 
2811   return false;
2812 }
2813 
2814 struct MapToDimensionDataTy {
2815   int N;
2816   isl_union_pw_multi_aff *Res;
2817 };
2818 
2819 // @brief Create a function that maps the elements of 'Set' to its N-th
2820 //        dimension.
2821 //
2822 // The result is added to 'User->Res'.
2823 //
2824 // @param Set The input set.
2825 // @param N   The dimension to map to.
2826 //
2827 // @returns   Zero if no error occurred, non-zero otherwise.
2828 static isl_stat mapToDimension_AddSet(__isl_take isl_set *Set, void *User) {
2829   struct MapToDimensionDataTy *Data = (struct MapToDimensionDataTy *)User;
2830   int Dim;
2831   isl_space *Space;
2832   isl_pw_multi_aff *PMA;
2833 
2834   Dim = isl_set_dim(Set, isl_dim_set);
2835   Space = isl_set_get_space(Set);
2836   PMA = isl_pw_multi_aff_project_out_map(Space, isl_dim_set, Data->N,
2837                                          Dim - Data->N);
2838   if (Data->N > 1)
2839     PMA = isl_pw_multi_aff_drop_dims(PMA, isl_dim_out, 0, Data->N - 1);
2840   Data->Res = isl_union_pw_multi_aff_add_pw_multi_aff(Data->Res, PMA);
2841 
2842   isl_set_free(Set);
2843 
2844   return isl_stat_ok;
2845 }
2846 
2847 // @brief Create a function that maps the elements of Domain to their Nth
2848 //        dimension.
2849 //
2850 // @param Domain The set of elements to map.
2851 // @param N      The dimension to map to.
2852 static __isl_give isl_multi_union_pw_aff *
2853 mapToDimension(__isl_take isl_union_set *Domain, int N) {
2854   if (N <= 0 || isl_union_set_is_empty(Domain)) {
2855     isl_union_set_free(Domain);
2856     return nullptr;
2857   }
2858 
2859   struct MapToDimensionDataTy Data;
2860   isl_space *Space;
2861 
2862   Space = isl_union_set_get_space(Domain);
2863   Data.N = N;
2864   Data.Res = isl_union_pw_multi_aff_empty(Space);
2865   if (isl_union_set_foreach_set(Domain, &mapToDimension_AddSet, &Data) < 0)
2866     Data.Res = isl_union_pw_multi_aff_free(Data.Res);
2867 
2868   isl_union_set_free(Domain);
2869   return isl_multi_union_pw_aff_from_union_pw_multi_aff(Data.Res);
2870 }
2871 
2872 ScopStmt *Scop::addScopStmt(BasicBlock *BB, Region *R) {
2873   ScopStmt *Stmt;
2874   if (BB) {
2875     Stmts.emplace_back(*this, *BB);
2876     Stmt = &Stmts.back();
2877     StmtMap[BB] = Stmt;
2878   } else {
2879     assert(R && "Either basic block or a region expected.");
2880     Stmts.emplace_back(*this, *R);
2881     Stmt = &Stmts.back();
2882     for (BasicBlock *BB : R->blocks())
2883       StmtMap[BB] = Stmt;
2884   }
2885   return Stmt;
2886 }
2887 
2888 void Scop::buildSchedule(
2889     Region *R, LoopInfo &LI,
2890     DenseMap<Loop *, std::pair<isl_schedule *, unsigned>> &LoopSchedules) {
2891 
2892   if (SD.isNonAffineSubRegion(R, &getRegion())) {
2893     Loop *L = getLoopSurroundingRegion(*R, LI);
2894     auto &LSchedulePair = LoopSchedules[L];
2895     ScopStmt *Stmt = getStmtForBasicBlock(R->getEntry());
2896     isl_set *Domain = Stmt->getDomain();
2897     auto *UDomain = isl_union_set_from_set(Domain);
2898     auto *StmtSchedule = isl_schedule_from_domain(UDomain);
2899     LSchedulePair.first = StmtSchedule;
2900     return;
2901   }
2902 
2903   ReversePostOrderTraversal<Region *> RTraversal(R);
2904   for (auto *RN : RTraversal) {
2905 
2906     if (RN->isSubRegion()) {
2907       Region *SubRegion = RN->getNodeAs<Region>();
2908       if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) {
2909         buildSchedule(SubRegion, LI, LoopSchedules);
2910         continue;
2911       }
2912     }
2913 
2914     Loop *L = getRegionNodeLoop(RN, LI);
2915     int LD = getRelativeLoopDepth(L);
2916     auto &LSchedulePair = LoopSchedules[L];
2917     LSchedulePair.second += getNumBlocksInRegionNode(RN);
2918 
2919     BasicBlock *BB = getRegionNodeBasicBlock(RN);
2920     ScopStmt *Stmt = getStmtForBasicBlock(BB);
2921     if (Stmt) {
2922       auto *UDomain = isl_union_set_from_set(Stmt->getDomain());
2923       auto *StmtSchedule = isl_schedule_from_domain(UDomain);
2924       LSchedulePair.first =
2925           combineInSequence(LSchedulePair.first, StmtSchedule);
2926     }
2927 
2928     unsigned NumVisited = LSchedulePair.second;
2929     while (L && NumVisited == L->getNumBlocks()) {
2930       auto *LDomain = isl_schedule_get_domain(LSchedulePair.first);
2931       if (auto *MUPA = mapToDimension(LDomain, LD + 1))
2932         LSchedulePair.first =
2933             isl_schedule_insert_partial_schedule(LSchedulePair.first, MUPA);
2934 
2935       auto *PL = L->getParentLoop();
2936       assert(LoopSchedules.count(PL));
2937       auto &PSchedulePair = LoopSchedules[PL];
2938       PSchedulePair.first =
2939           combineInSequence(PSchedulePair.first, LSchedulePair.first);
2940       PSchedulePair.second += NumVisited;
2941 
2942       L = PL;
2943       NumVisited = PSchedulePair.second;
2944     }
2945   }
2946 }
2947 
2948 ScopStmt *Scop::getStmtForBasicBlock(BasicBlock *BB) const {
2949   auto StmtMapIt = StmtMap.find(BB);
2950   if (StmtMapIt == StmtMap.end())
2951     return nullptr;
2952   return StmtMapIt->second;
2953 }
2954 
2955 int Scop::getRelativeLoopDepth(const Loop *L) const {
2956   Loop *OuterLoop =
2957       L ? R.outermostLoopInRegion(const_cast<Loop *>(L)) : nullptr;
2958   if (!OuterLoop)
2959     return -1;
2960   return L->getLoopDepth() - OuterLoop->getLoopDepth();
2961 }
2962 
2963 void ScopInfo::buildPHIAccesses(PHINode *PHI, Region &R,
2964                                 Region *NonAffineSubRegion, bool IsExitBlock) {
2965 
2966   // PHI nodes that are in the exit block of the region, hence if IsExitBlock is
2967   // true, are not modeled as ordinary PHI nodes as they are not part of the
2968   // region. However, we model the operands in the predecessor blocks that are
2969   // part of the region as regular scalar accesses.
2970 
2971   // If we can synthesize a PHI we can skip it, however only if it is in
2972   // the region. If it is not it can only be in the exit block of the region.
2973   // In this case we model the operands but not the PHI itself.
2974   if (!IsExitBlock && canSynthesize(PHI, LI, SE, &R))
2975     return;
2976 
2977   // PHI nodes are modeled as if they had been demoted prior to the SCoP
2978   // detection. Hence, the PHI is a load of a new memory location in which the
2979   // incoming value was written at the end of the incoming basic block.
2980   bool OnlyNonAffineSubRegionOperands = true;
2981   for (unsigned u = 0; u < PHI->getNumIncomingValues(); u++) {
2982     Value *Op = PHI->getIncomingValue(u);
2983     BasicBlock *OpBB = PHI->getIncomingBlock(u);
2984 
2985     // Do not build scalar dependences inside a non-affine subregion.
2986     if (NonAffineSubRegion && NonAffineSubRegion->contains(OpBB))
2987       continue;
2988 
2989     OnlyNonAffineSubRegionOperands = false;
2990 
2991     if (!R.contains(OpBB))
2992       continue;
2993 
2994     Instruction *OpI = dyn_cast<Instruction>(Op);
2995     if (OpI) {
2996       BasicBlock *OpIBB = OpI->getParent();
2997       // As we pretend there is a use (or more precise a write) of OpI in OpBB
2998       // we have to insert a scalar dependence from the definition of OpI to
2999       // OpBB if the definition is not in OpBB.
3000       if (OpIBB != OpBB) {
3001         addScalarReadAccess(OpI, PHI, OpBB);
3002         addScalarWriteAccess(OpI);
3003       }
3004     } else if (ModelReadOnlyScalars && !isa<Constant>(Op)) {
3005       addScalarReadAccess(Op, PHI, OpBB);
3006     }
3007 
3008     addPHIWriteAccess(PHI, OpBB, Op, IsExitBlock);
3009   }
3010 
3011   if (!OnlyNonAffineSubRegionOperands && !IsExitBlock) {
3012     addPHIReadAccess(PHI);
3013   }
3014 }
3015 
3016 bool ScopInfo::buildScalarDependences(Instruction *Inst, Region *R,
3017                                       Region *NonAffineSubRegion) {
3018   bool canSynthesizeInst = canSynthesize(Inst, LI, SE, R);
3019   if (isIgnoredIntrinsic(Inst))
3020     return false;
3021 
3022   bool AnyCrossStmtUse = false;
3023   BasicBlock *ParentBB = Inst->getParent();
3024 
3025   for (User *U : Inst->users()) {
3026     Instruction *UI = dyn_cast<Instruction>(U);
3027 
3028     // Ignore the strange user
3029     if (UI == 0)
3030       continue;
3031 
3032     BasicBlock *UseParent = UI->getParent();
3033 
3034     // Ignore the users in the same BB (statement)
3035     if (UseParent == ParentBB)
3036       continue;
3037 
3038     // Do not build scalar dependences inside a non-affine subregion.
3039     if (NonAffineSubRegion && NonAffineSubRegion->contains(UseParent))
3040       continue;
3041 
3042     // Check whether or not the use is in the SCoP.
3043     if (!R->contains(UseParent)) {
3044       AnyCrossStmtUse = true;
3045       continue;
3046     }
3047 
3048     // If the instruction can be synthesized and the user is in the region
3049     // we do not need to add scalar dependences.
3050     if (canSynthesizeInst)
3051       continue;
3052 
3053     // No need to translate these scalar dependences into polyhedral form,
3054     // because synthesizable scalars can be generated by the code generator.
3055     if (canSynthesize(UI, LI, SE, R))
3056       continue;
3057 
3058     // Skip PHI nodes in the region as they handle their operands on their own.
3059     if (isa<PHINode>(UI))
3060       continue;
3061 
3062     // Now U is used in another statement.
3063     AnyCrossStmtUse = true;
3064 
3065     // Do not build a read access that is not in the current SCoP
3066     // Use the def instruction as base address of the MemoryAccess, so that it
3067     // will become the name of the scalar access in the polyhedral form.
3068     addScalarReadAccess(Inst, UI);
3069   }
3070 
3071   if (ModelReadOnlyScalars && !isa<PHINode>(Inst)) {
3072     for (Value *Op : Inst->operands()) {
3073       if (canSynthesize(Op, LI, SE, R))
3074         continue;
3075 
3076       if (Instruction *OpInst = dyn_cast<Instruction>(Op))
3077         if (R->contains(OpInst))
3078           continue;
3079 
3080       if (isa<Constant>(Op))
3081         continue;
3082 
3083       addScalarReadAccess(Op, Inst);
3084     }
3085   }
3086 
3087   return AnyCrossStmtUse;
3088 }
3089 
3090 extern MapInsnToMemAcc InsnToMemAcc;
3091 
3092 void ScopInfo::buildMemoryAccess(
3093     Instruction *Inst, Loop *L, Region *R,
3094     const ScopDetection::BoxedLoopsSetTy *BoxedLoops) {
3095   unsigned Size;
3096   Type *SizeType;
3097   Value *Val;
3098   enum MemoryAccess::AccessType Type;
3099 
3100   if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
3101     SizeType = Load->getType();
3102     Size = TD->getTypeStoreSize(SizeType);
3103     Type = MemoryAccess::READ;
3104     Val = Load;
3105   } else {
3106     StoreInst *Store = cast<StoreInst>(Inst);
3107     SizeType = Store->getValueOperand()->getType();
3108     Size = TD->getTypeStoreSize(SizeType);
3109     Type = MemoryAccess::MUST_WRITE;
3110     Val = Store->getValueOperand();
3111   }
3112 
3113   auto Address = getPointerOperand(*Inst);
3114 
3115   const SCEV *AccessFunction = SE->getSCEVAtScope(Address, L);
3116   const SCEVUnknown *BasePointer =
3117       dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction));
3118 
3119   assert(BasePointer && "Could not find base pointer");
3120   AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
3121 
3122   if (isa<GetElementPtrInst>(Address) || isa<BitCastInst>(Address)) {
3123     auto NewAddress = Address;
3124     if (auto *BitCast = dyn_cast<BitCastInst>(Address)) {
3125       auto Src = BitCast->getOperand(0);
3126       auto SrcTy = Src->getType();
3127       auto DstTy = BitCast->getType();
3128       if (SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits())
3129         NewAddress = Src;
3130     }
3131 
3132     if (auto *GEP = dyn_cast<GetElementPtrInst>(NewAddress)) {
3133       std::vector<const SCEV *> Subscripts;
3134       std::vector<int> Sizes;
3135       std::tie(Subscripts, Sizes) = getIndexExpressionsFromGEP(GEP, *SE);
3136       auto BasePtr = GEP->getOperand(0);
3137 
3138       std::vector<const SCEV *> SizesSCEV;
3139 
3140       bool AllAffineSubcripts = true;
3141       for (auto Subscript : Subscripts)
3142         if (!isAffineExpr(R, Subscript, *SE)) {
3143           AllAffineSubcripts = false;
3144           break;
3145         }
3146 
3147       if (AllAffineSubcripts && Sizes.size() > 0) {
3148         for (auto V : Sizes)
3149           SizesSCEV.push_back(SE->getSCEV(ConstantInt::get(
3150               IntegerType::getInt64Ty(BasePtr->getContext()), V)));
3151         SizesSCEV.push_back(SE->getSCEV(ConstantInt::get(
3152             IntegerType::getInt64Ty(BasePtr->getContext()), Size)));
3153 
3154         addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, true,
3155                           Subscripts, SizesSCEV, Val);
3156         return;
3157       }
3158     }
3159   }
3160 
3161   auto AccItr = InsnToMemAcc.find(Inst);
3162   if (PollyDelinearize && AccItr != InsnToMemAcc.end()) {
3163     addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, true,
3164                       AccItr->second.DelinearizedSubscripts,
3165                       AccItr->second.Shape->DelinearizedSizes, Val);
3166     return;
3167   }
3168 
3169   // Check if the access depends on a loop contained in a non-affine subregion.
3170   bool isVariantInNonAffineLoop = false;
3171   if (BoxedLoops) {
3172     SetVector<const Loop *> Loops;
3173     findLoops(AccessFunction, Loops);
3174     for (const Loop *L : Loops)
3175       if (BoxedLoops->count(L))
3176         isVariantInNonAffineLoop = true;
3177   }
3178 
3179   bool IsAffine = !isVariantInNonAffineLoop &&
3180                   isAffineExpr(R, AccessFunction, *SE, BasePointer->getValue());
3181 
3182   // FIXME: Size of the number of bytes of an array element, not the number of
3183   // elements as probably intended here.
3184   const SCEV *SizeSCEV =
3185       SE->getConstant(TD->getIntPtrType(Inst->getContext()), Size);
3186 
3187   if (!IsAffine && Type == MemoryAccess::MUST_WRITE)
3188     Type = MemoryAccess::MAY_WRITE;
3189 
3190   addExplicitAccess(Inst, Type, BasePointer->getValue(), Size, IsAffine,
3191                     ArrayRef<const SCEV *>(AccessFunction),
3192                     ArrayRef<const SCEV *>(SizeSCEV), Val);
3193 }
3194 
3195 void ScopInfo::buildAccessFunctions(Region &R, Region &SR) {
3196 
3197   if (SD->isNonAffineSubRegion(&SR, &R)) {
3198     for (BasicBlock *BB : SR.blocks())
3199       buildAccessFunctions(R, *BB, &SR);
3200     return;
3201   }
3202 
3203   for (auto I = SR.element_begin(), E = SR.element_end(); I != E; ++I)
3204     if (I->isSubRegion())
3205       buildAccessFunctions(R, *I->getNodeAs<Region>());
3206     else
3207       buildAccessFunctions(R, *I->getNodeAs<BasicBlock>());
3208 }
3209 
3210 void ScopInfo::buildStmts(Region &SR) {
3211   Region *R = getRegion();
3212 
3213   if (SD->isNonAffineSubRegion(&SR, R)) {
3214     scop->addScopStmt(nullptr, &SR);
3215     return;
3216   }
3217 
3218   for (auto I = SR.element_begin(), E = SR.element_end(); I != E; ++I)
3219     if (I->isSubRegion())
3220       buildStmts(*I->getNodeAs<Region>());
3221     else
3222       scop->addScopStmt(I->getNodeAs<BasicBlock>(), nullptr);
3223 }
3224 
3225 void ScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB,
3226                                     Region *NonAffineSubRegion,
3227                                     bool IsExitBlock) {
3228   Loop *L = LI->getLoopFor(&BB);
3229 
3230   // The set of loops contained in non-affine subregions that are part of R.
3231   const ScopDetection::BoxedLoopsSetTy *BoxedLoops = SD->getBoxedLoops(&R);
3232 
3233   for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) {
3234     Instruction *Inst = I;
3235 
3236     PHINode *PHI = dyn_cast<PHINode>(Inst);
3237     if (PHI)
3238       buildPHIAccesses(PHI, R, NonAffineSubRegion, IsExitBlock);
3239 
3240     // For the exit block we stop modeling after the last PHI node.
3241     if (!PHI && IsExitBlock)
3242       break;
3243 
3244     if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst))
3245       buildMemoryAccess(Inst, L, &R, BoxedLoops);
3246 
3247     if (isIgnoredIntrinsic(Inst))
3248       continue;
3249 
3250     if (buildScalarDependences(Inst, &R, NonAffineSubRegion)) {
3251       if (!isa<StoreInst>(Inst))
3252         addScalarWriteAccess(Inst);
3253     }
3254   }
3255 }
3256 
3257 void ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst,
3258                                MemoryAccess::AccessType Type,
3259                                Value *BaseAddress, unsigned ElemBytes,
3260                                bool Affine, Value *AccessValue,
3261                                ArrayRef<const SCEV *> Subscripts,
3262                                ArrayRef<const SCEV *> Sizes,
3263                                MemoryAccess::AccessOrigin Origin) {
3264   ScopStmt *Stmt = scop->getStmtForBasicBlock(BB);
3265 
3266   // Do not create a memory access for anything not in the SCoP. It would be
3267   // ignored anyway.
3268   if (!Stmt)
3269     return;
3270 
3271   AccFuncSetType &AccList = AccFuncMap[BB];
3272   size_t Identifier = AccList.size();
3273 
3274   Value *BaseAddr = BaseAddress;
3275   std::string BaseName = getIslCompatibleName("MemRef_", BaseAddr, "");
3276 
3277   std::string IdName = "__polly_array_ref_" + std::to_string(Identifier);
3278   isl_id *Id = isl_id_alloc(ctx, IdName.c_str(), nullptr);
3279 
3280   bool isApproximated =
3281       Stmt->isRegionStmt() && (Stmt->getRegion()->getEntry() != BB);
3282   if (isApproximated && Type == MemoryAccess::MUST_WRITE)
3283     Type = MemoryAccess::MAY_WRITE;
3284 
3285   AccList.emplace_back(Stmt, Inst, Id, Type, BaseAddress, ElemBytes, Affine,
3286                        Subscripts, Sizes, AccessValue, Origin, BaseName);
3287   Stmt->addAccess(&AccList.back());
3288 }
3289 
3290 void ScopInfo::addExplicitAccess(
3291     Instruction *MemAccInst, MemoryAccess::AccessType Type, Value *BaseAddress,
3292     unsigned ElemBytes, bool IsAffine, ArrayRef<const SCEV *> Subscripts,
3293     ArrayRef<const SCEV *> Sizes, Value *AccessValue) {
3294   assert(isa<LoadInst>(MemAccInst) || isa<StoreInst>(MemAccInst));
3295   assert(isa<LoadInst>(MemAccInst) == (Type == MemoryAccess::READ));
3296   addMemoryAccess(MemAccInst->getParent(), MemAccInst, Type, BaseAddress,
3297                   ElemBytes, IsAffine, AccessValue, Subscripts, Sizes,
3298                   MemoryAccess::EXPLICIT);
3299 }
3300 void ScopInfo::addScalarWriteAccess(Instruction *Value) {
3301   addMemoryAccess(Value->getParent(), Value, MemoryAccess::MUST_WRITE, Value, 1,
3302                   true, Value, ArrayRef<const SCEV *>(),
3303                   ArrayRef<const SCEV *>(), MemoryAccess::SCALAR);
3304 }
3305 void ScopInfo::addScalarReadAccess(Value *Value, Instruction *User) {
3306   assert(!isa<PHINode>(User));
3307   addMemoryAccess(User->getParent(), User, MemoryAccess::READ, Value, 1, true,
3308                   Value, ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
3309                   MemoryAccess::SCALAR);
3310 }
3311 void ScopInfo::addScalarReadAccess(Value *Value, PHINode *User,
3312                                    BasicBlock *UserBB) {
3313   addMemoryAccess(UserBB, User, MemoryAccess::READ, Value, 1, true, Value,
3314                   ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
3315                   MemoryAccess::SCALAR);
3316 }
3317 void ScopInfo::addPHIWriteAccess(PHINode *PHI, BasicBlock *IncomingBlock,
3318                                  Value *IncomingValue, bool IsExitBlock) {
3319   addMemoryAccess(IncomingBlock, IncomingBlock->getTerminator(),
3320                   MemoryAccess::MUST_WRITE, PHI, 1, true, IncomingValue,
3321                   ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
3322                   IsExitBlock ? MemoryAccess::SCALAR : MemoryAccess::PHI);
3323 }
3324 void ScopInfo::addPHIReadAccess(PHINode *PHI) {
3325   addMemoryAccess(PHI->getParent(), PHI, MemoryAccess::READ, PHI, 1, true, PHI,
3326                   ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
3327                   MemoryAccess::PHI);
3328 }
3329 
3330 void ScopInfo::buildScop(Region &R, DominatorTree &DT) {
3331   unsigned MaxLoopDepth = getMaxLoopDepthInRegion(R, *LI, *SD);
3332   scop = new Scop(R, AccFuncMap, *SD, *SE, DT, ctx, MaxLoopDepth);
3333 
3334   buildStmts(R);
3335   buildAccessFunctions(R, R);
3336 
3337   // In case the region does not have an exiting block we will later (during
3338   // code generation) split the exit block. This will move potential PHI nodes
3339   // from the current exit block into the new region exiting block. Hence, PHI
3340   // nodes that are at this point not part of the region will be.
3341   // To handle these PHI nodes later we will now model their operands as scalar
3342   // accesses. Note that we do not model anything in the exit block if we have
3343   // an exiting block in the region, as there will not be any splitting later.
3344   if (!R.getExitingBlock())
3345     buildAccessFunctions(R, *R.getExit(), nullptr, /* IsExitBlock */ true);
3346 
3347   scop->init(*LI, *AA);
3348 }
3349 
3350 void ScopInfo::print(raw_ostream &OS, const Module *) const {
3351   if (!scop) {
3352     OS << "Invalid Scop!\n";
3353     return;
3354   }
3355 
3356   scop->print(OS);
3357 }
3358 
3359 void ScopInfo::clear() {
3360   AccFuncMap.clear();
3361   if (scop) {
3362     delete scop;
3363     scop = 0;
3364   }
3365 }
3366 
3367 //===----------------------------------------------------------------------===//
3368 ScopInfo::ScopInfo() : RegionPass(ID), scop(0) {
3369   ctx = isl_ctx_alloc();
3370   isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
3371 }
3372 
3373 ScopInfo::~ScopInfo() {
3374   clear();
3375   isl_ctx_free(ctx);
3376 }
3377 
3378 void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
3379   AU.addRequiredID(IndependentBlocksID);
3380   AU.addRequired<LoopInfoWrapperPass>();
3381   AU.addRequired<RegionInfoPass>();
3382   AU.addRequired<DominatorTreeWrapperPass>();
3383   AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
3384   AU.addRequiredTransitive<ScopDetection>();
3385   AU.addRequired<AAResultsWrapperPass>();
3386   AU.setPreservesAll();
3387 }
3388 
3389 bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
3390   SD = &getAnalysis<ScopDetection>();
3391 
3392   if (!SD->isMaxRegionInScop(*R))
3393     return false;
3394 
3395   Function *F = R->getEntry()->getParent();
3396   SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
3397   LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
3398   AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
3399   TD = &F->getParent()->getDataLayout();
3400   DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
3401 
3402   buildScop(*R, DT);
3403 
3404   DEBUG(scop->print(dbgs()));
3405 
3406   if (scop->isEmpty() || !scop->hasFeasibleRuntimeContext()) {
3407     delete scop;
3408     scop = nullptr;
3409     return false;
3410   }
3411 
3412   // Statistics.
3413   ++ScopFound;
3414   if (scop->getMaxLoopDepth() > 0)
3415     ++RichScopFound;
3416   return false;
3417 }
3418 
3419 char ScopInfo::ID = 0;
3420 
3421 Pass *polly::createScopInfoPass() { return new ScopInfo(); }
3422 
3423 INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops",
3424                       "Polly - Create polyhedral description of Scops", false,
3425                       false);
3426 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
3427 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
3428 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
3429 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
3430 INITIALIZE_PASS_DEPENDENCY(ScopDetection);
3431 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
3432 INITIALIZE_PASS_END(ScopInfo, "polly-scops",
3433                     "Polly - Create polyhedral description of Scops", false,
3434                     false)
3435