1 //===--------- ScopInfo.cpp ----------------------------------------------===//
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/ScopInfo.h"
21 #include "polly/LinkAllPasses.h"
22 #include "polly/Options.h"
23 #include "polly/ScopBuilder.h"
24 #include "polly/Support/GICHelper.h"
25 #include "polly/Support/SCEVValidator.h"
26 #include "polly/Support/ScopHelper.h"
27 #include "llvm/ADT/DepthFirstIterator.h"
28 #include "llvm/ADT/MapVector.h"
29 #include "llvm/ADT/PostOrderIterator.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/SetVector.h"
32 #include "llvm/ADT/Statistic.h"
33 #include "llvm/ADT/StringExtras.h"
34 #include "llvm/Analysis/AliasAnalysis.h"
35 #include "llvm/Analysis/AssumptionCache.h"
36 #include "llvm/Analysis/Loads.h"
37 #include "llvm/Analysis/LoopInfo.h"
38 #include "llvm/Analysis/LoopIterator.h"
39 #include "llvm/Analysis/RegionIterator.h"
40 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
41 #include "llvm/IR/DiagnosticInfo.h"
42 #include "llvm/Support/Debug.h"
43 #include "isl/aff.h"
44 #include "isl/constraint.h"
45 #include "isl/local_space.h"
46 #include "isl/map.h"
47 #include "isl/options.h"
48 #include "isl/printer.h"
49 #include "isl/schedule.h"
50 #include "isl/schedule_node.h"
51 #include "isl/set.h"
52 #include "isl/union_map.h"
53 #include "isl/union_set.h"
54 #include "isl/val.h"
55 #include <sstream>
56 #include <string>
57 #include <vector>
58 
59 using namespace llvm;
60 using namespace polly;
61 
62 #define DEBUG_TYPE "polly-scops"
63 
64 // The maximal number of basic sets we allow during domain construction to
65 // be created. More complex scops will result in very high compile time and
66 // are also unlikely to result in good code
67 static int const MaxDisjunctionsInDomain = 20;
68 
69 static cl::opt<bool> PollyRemarksMinimal(
70     "polly-remarks-minimal",
71     cl::desc("Do not emit remarks about assumptions that are known"),
72     cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::cat(PollyCategory));
73 
74 // Multiplicative reductions can be disabled separately as these kind of
75 // operations can overflow easily. Additive reductions and bit operations
76 // are in contrast pretty stable.
77 static cl::opt<bool> DisableMultiplicativeReductions(
78     "polly-disable-multiplicative-reductions",
79     cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore,
80     cl::init(false), cl::cat(PollyCategory));
81 
82 static cl::opt<unsigned> RunTimeChecksMaxParameters(
83     "polly-rtc-max-parameters",
84     cl::desc("The maximal number of parameters allowed in RTCs."), cl::Hidden,
85     cl::ZeroOrMore, cl::init(8), cl::cat(PollyCategory));
86 
87 static cl::opt<unsigned> RunTimeChecksMaxArraysPerGroup(
88     "polly-rtc-max-arrays-per-group",
89     cl::desc("The maximal number of arrays to compare in each alias group."),
90     cl::Hidden, cl::ZeroOrMore, cl::init(20), cl::cat(PollyCategory));
91 
92 static cl::opt<std::string> UserContextStr(
93     "polly-context", cl::value_desc("isl parameter set"),
94     cl::desc("Provide additional constraints on the context parameters"),
95     cl::init(""), cl::cat(PollyCategory));
96 
97 static cl::opt<bool> DetectReductions("polly-detect-reductions",
98                                       cl::desc("Detect and exploit reductions"),
99                                       cl::Hidden, cl::ZeroOrMore,
100                                       cl::init(true), cl::cat(PollyCategory));
101 
102 static cl::opt<bool>
103     IslOnErrorAbort("polly-on-isl-error-abort",
104                     cl::desc("Abort if an isl error is encountered"),
105                     cl::init(true), cl::cat(PollyCategory));
106 
107 //===----------------------------------------------------------------------===//
108 
109 // Create a sequence of two schedules. Either argument may be null and is
110 // interpreted as the empty schedule. Can also return null if both schedules are
111 // empty.
112 static __isl_give isl_schedule *
113 combineInSequence(__isl_take isl_schedule *Prev,
114                   __isl_take isl_schedule *Succ) {
115   if (!Prev)
116     return Succ;
117   if (!Succ)
118     return Prev;
119 
120   return isl_schedule_sequence(Prev, Succ);
121 }
122 
123 static __isl_give isl_set *addRangeBoundsToSet(__isl_take isl_set *S,
124                                                const ConstantRange &Range,
125                                                int dim,
126                                                enum isl_dim_type type) {
127   isl_val *V;
128   isl_ctx *ctx = isl_set_get_ctx(S);
129 
130   bool useLowerUpperBound = Range.isSignWrappedSet() && !Range.isFullSet();
131   const auto LB = useLowerUpperBound ? Range.getLower() : Range.getSignedMin();
132   V = isl_valFromAPInt(ctx, LB, true);
133   isl_set *SLB = isl_set_lower_bound_val(isl_set_copy(S), type, dim, V);
134 
135   const auto UB = useLowerUpperBound ? Range.getUpper() : Range.getSignedMax();
136   V = isl_valFromAPInt(ctx, UB, true);
137   if (useLowerUpperBound)
138     V = isl_val_sub_ui(V, 1);
139   isl_set *SUB = isl_set_upper_bound_val(S, type, dim, V);
140 
141   if (useLowerUpperBound)
142     return isl_set_union(SLB, SUB);
143   else
144     return isl_set_intersect(SLB, SUB);
145 }
146 
147 static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) {
148   LoadInst *BasePtrLI = dyn_cast<LoadInst>(BasePtr);
149   if (!BasePtrLI)
150     return nullptr;
151 
152   if (!S->contains(BasePtrLI))
153     return nullptr;
154 
155   ScalarEvolution &SE = *S->getSE();
156 
157   auto *OriginBaseSCEV =
158       SE.getPointerBase(SE.getSCEV(BasePtrLI->getPointerOperand()));
159   if (!OriginBaseSCEV)
160     return nullptr;
161 
162   auto *OriginBaseSCEVUnknown = dyn_cast<SCEVUnknown>(OriginBaseSCEV);
163   if (!OriginBaseSCEVUnknown)
164     return nullptr;
165 
166   return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue(),
167                              ScopArrayInfo::MK_Array);
168 }
169 
170 ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx,
171                              ArrayRef<const SCEV *> Sizes, enum MemoryKind Kind,
172                              const DataLayout &DL, Scop *S,
173                              const char *BaseName)
174     : BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), DL(DL), S(*S) {
175   std::string BasePtrName =
176       BaseName ? BaseName : getIslCompatibleName("MemRef_", BasePtr,
177                                                  Kind == MK_PHI ? "__phi" : "");
178   Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
179 
180   updateSizes(Sizes);
181 
182   if (!BasePtr) {
183     BasePtrOriginSAI = nullptr;
184     return;
185   }
186 
187   BasePtrOriginSAI = identifyBasePtrOriginSAI(S, BasePtr);
188   if (BasePtrOriginSAI)
189     const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
190 }
191 
192 __isl_give isl_space *ScopArrayInfo::getSpace() const {
193   auto *Space =
194       isl_space_set_alloc(isl_id_get_ctx(Id), 0, getNumberOfDimensions());
195   Space = isl_space_set_tuple_id(Space, isl_dim_set, isl_id_copy(Id));
196   return Space;
197 }
198 
199 void ScopArrayInfo::updateElementType(Type *NewElementType) {
200   if (NewElementType == ElementType)
201     return;
202 
203   auto OldElementSize = DL.getTypeAllocSizeInBits(ElementType);
204   auto NewElementSize = DL.getTypeAllocSizeInBits(NewElementType);
205 
206   if (NewElementSize == OldElementSize || NewElementSize == 0)
207     return;
208 
209   if (NewElementSize % OldElementSize == 0 && NewElementSize < OldElementSize) {
210     ElementType = NewElementType;
211   } else {
212     auto GCD = GreatestCommonDivisor64(NewElementSize, OldElementSize);
213     ElementType = IntegerType::get(ElementType->getContext(), GCD);
214   }
215 }
216 
217 bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes) {
218   int SharedDims = std::min(NewSizes.size(), DimensionSizes.size());
219   int ExtraDimsNew = NewSizes.size() - SharedDims;
220   int ExtraDimsOld = DimensionSizes.size() - SharedDims;
221   for (int i = 0; i < SharedDims; i++)
222     if (NewSizes[i + ExtraDimsNew] != DimensionSizes[i + ExtraDimsOld])
223       return false;
224 
225   if (DimensionSizes.size() >= NewSizes.size())
226     return true;
227 
228   DimensionSizes.clear();
229   DimensionSizes.insert(DimensionSizes.begin(), NewSizes.begin(),
230                         NewSizes.end());
231   for (isl_pw_aff *Size : DimensionSizesPw)
232     isl_pw_aff_free(Size);
233   DimensionSizesPw.clear();
234   for (const SCEV *Expr : DimensionSizes) {
235     isl_pw_aff *Size = S.getPwAffOnly(Expr);
236     DimensionSizesPw.push_back(Size);
237   }
238   return true;
239 }
240 
241 ScopArrayInfo::~ScopArrayInfo() {
242   isl_id_free(Id);
243   for (isl_pw_aff *Size : DimensionSizesPw)
244     isl_pw_aff_free(Size);
245 }
246 
247 std::string ScopArrayInfo::getName() const { return isl_id_get_name(Id); }
248 
249 int ScopArrayInfo::getElemSizeInBytes() const {
250   return DL.getTypeAllocSize(ElementType);
251 }
252 
253 __isl_give isl_id *ScopArrayInfo::getBasePtrId() const {
254   return isl_id_copy(Id);
255 }
256 
257 void ScopArrayInfo::dump() const { print(errs()); }
258 
259 void ScopArrayInfo::print(raw_ostream &OS, bool SizeAsPwAff) const {
260   OS.indent(8) << *getElementType() << " " << getName();
261   if (getNumberOfDimensions() > 0)
262     OS << "[*]";
263   for (unsigned u = 1; u < getNumberOfDimensions(); u++) {
264     OS << "[";
265 
266     if (SizeAsPwAff) {
267       auto *Size = getDimensionSizePw(u);
268       OS << " " << Size << " ";
269       isl_pw_aff_free(Size);
270     } else {
271       OS << *getDimensionSize(u);
272     }
273 
274     OS << "]";
275   }
276 
277   OS << ";";
278 
279   if (BasePtrOriginSAI)
280     OS << " [BasePtrOrigin: " << BasePtrOriginSAI->getName() << "]";
281 
282   OS << " // Element size " << getElemSizeInBytes() << "\n";
283 }
284 
285 const ScopArrayInfo *
286 ScopArrayInfo::getFromAccessFunction(__isl_keep isl_pw_multi_aff *PMA) {
287   isl_id *Id = isl_pw_multi_aff_get_tuple_id(PMA, isl_dim_out);
288   assert(Id && "Output dimension didn't have an ID");
289   return getFromId(Id);
290 }
291 
292 const ScopArrayInfo *ScopArrayInfo::getFromId(__isl_take isl_id *Id) {
293   void *User = isl_id_get_user(Id);
294   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
295   isl_id_free(Id);
296   return SAI;
297 }
298 
299 void MemoryAccess::wrapConstantDimensions() {
300   auto *SAI = getScopArrayInfo();
301   auto *ArraySpace = SAI->getSpace();
302   auto *Ctx = isl_space_get_ctx(ArraySpace);
303   unsigned DimsArray = SAI->getNumberOfDimensions();
304 
305   auto *DivModAff = isl_multi_aff_identity(isl_space_map_from_domain_and_range(
306       isl_space_copy(ArraySpace), isl_space_copy(ArraySpace)));
307   auto *LArraySpace = isl_local_space_from_space(ArraySpace);
308 
309   // Begin with last dimension, to iteratively carry into higher dimensions.
310   for (int i = DimsArray - 1; i > 0; i--) {
311     auto *DimSize = SAI->getDimensionSize(i);
312     auto *DimSizeCst = dyn_cast<SCEVConstant>(DimSize);
313 
314     // This transformation is not applicable to dimensions with dynamic size.
315     if (!DimSizeCst)
316       continue;
317 
318     auto *DimSizeVal = isl_valFromAPInt(Ctx, DimSizeCst->getAPInt(), false);
319     auto *Var = isl_aff_var_on_domain(isl_local_space_copy(LArraySpace),
320                                       isl_dim_set, i);
321     auto *PrevVar = isl_aff_var_on_domain(isl_local_space_copy(LArraySpace),
322                                           isl_dim_set, i - 1);
323 
324     // Compute: index % size
325     // Modulo must apply in the divide of the previous iteration, if any.
326     auto *Modulo = isl_aff_copy(Var);
327     Modulo = isl_aff_mod_val(Modulo, isl_val_copy(DimSizeVal));
328     Modulo = isl_aff_pullback_multi_aff(Modulo, isl_multi_aff_copy(DivModAff));
329 
330     // Compute: floor(index / size)
331     auto *Divide = Var;
332     Divide = isl_aff_div(
333         Divide,
334         isl_aff_val_on_domain(isl_local_space_copy(LArraySpace), DimSizeVal));
335     Divide = isl_aff_floor(Divide);
336     Divide = isl_aff_add(Divide, PrevVar);
337     Divide = isl_aff_pullback_multi_aff(Divide, isl_multi_aff_copy(DivModAff));
338 
339     // Apply Modulo and Divide.
340     DivModAff = isl_multi_aff_set_aff(DivModAff, i, Modulo);
341     DivModAff = isl_multi_aff_set_aff(DivModAff, i - 1, Divide);
342   }
343 
344   // Apply all modulo/divides on the accesses.
345   AccessRelation =
346       isl_map_apply_range(AccessRelation, isl_map_from_multi_aff(DivModAff));
347   AccessRelation = isl_map_detect_equalities(AccessRelation);
348   isl_local_space_free(LArraySpace);
349 }
350 
351 void MemoryAccess::updateDimensionality() {
352   auto *SAI = getScopArrayInfo();
353   auto *ArraySpace = SAI->getSpace();
354   auto *AccessSpace = isl_space_range(isl_map_get_space(AccessRelation));
355   auto *Ctx = isl_space_get_ctx(AccessSpace);
356 
357   auto DimsArray = isl_space_dim(ArraySpace, isl_dim_set);
358   auto DimsAccess = isl_space_dim(AccessSpace, isl_dim_set);
359   auto DimsMissing = DimsArray - DimsAccess;
360 
361   auto *BB = getStatement()->getEntryBlock();
362   auto &DL = BB->getModule()->getDataLayout();
363   unsigned ArrayElemSize = SAI->getElemSizeInBytes();
364   unsigned ElemBytes = DL.getTypeAllocSize(getElementType());
365 
366   auto *Map = isl_map_from_domain_and_range(
367       isl_set_universe(AccessSpace),
368       isl_set_universe(isl_space_copy(ArraySpace)));
369 
370   for (unsigned i = 0; i < DimsMissing; i++)
371     Map = isl_map_fix_si(Map, isl_dim_out, i, 0);
372 
373   for (unsigned i = DimsMissing; i < DimsArray; i++)
374     Map = isl_map_equate(Map, isl_dim_in, i - DimsMissing, isl_dim_out, i);
375 
376   AccessRelation = isl_map_apply_range(AccessRelation, Map);
377 
378   // For the non delinearized arrays, divide the access function of the last
379   // subscript by the size of the elements in the array.
380   //
381   // A stride one array access in C expressed as A[i] is expressed in
382   // LLVM-IR as something like A[i * elementsize]. This hides the fact that
383   // two subsequent values of 'i' index two values that are stored next to
384   // each other in memory. By this division we make this characteristic
385   // obvious again. If the base pointer was accessed with offsets not divisible
386   // by the accesses element size, we will have chosen a smaller ArrayElemSize
387   // that divides the offsets of all accesses to this base pointer.
388   if (DimsAccess == 1) {
389     isl_val *V = isl_val_int_from_si(Ctx, ArrayElemSize);
390     AccessRelation = isl_map_floordiv_val(AccessRelation, V);
391   }
392 
393   // We currently do this only if we added at least one dimension, which means
394   // some dimension's indices have not been specified, an indicator that some
395   // index values have been added together.
396   // TODO: Investigate general usefulness; Effect on unit tests is to make index
397   // expressions more complicated.
398   if (DimsMissing)
399     wrapConstantDimensions();
400 
401   if (!isAffine())
402     computeBoundsOnAccessRelation(ArrayElemSize);
403 
404   // Introduce multi-element accesses in case the type loaded by this memory
405   // access is larger than the canonical element type of the array.
406   //
407   // An access ((float *)A)[i] to an array char *A is modeled as
408   // {[i] -> A[o] : 4 i <= o <= 4 i + 3
409   if (ElemBytes > ArrayElemSize) {
410     assert(ElemBytes % ArrayElemSize == 0 &&
411            "Loaded element size should be multiple of canonical element size");
412     auto *Map = isl_map_from_domain_and_range(
413         isl_set_universe(isl_space_copy(ArraySpace)),
414         isl_set_universe(isl_space_copy(ArraySpace)));
415     for (unsigned i = 0; i < DimsArray - 1; i++)
416       Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
417 
418     isl_constraint *C;
419     isl_local_space *LS;
420 
421     LS = isl_local_space_from_space(isl_map_get_space(Map));
422     int Num = ElemBytes / getScopArrayInfo()->getElemSizeInBytes();
423 
424     C = isl_constraint_alloc_inequality(isl_local_space_copy(LS));
425     C = isl_constraint_set_constant_val(C, isl_val_int_from_si(Ctx, Num - 1));
426     C = isl_constraint_set_coefficient_si(C, isl_dim_in, DimsArray - 1, 1);
427     C = isl_constraint_set_coefficient_si(C, isl_dim_out, DimsArray - 1, -1);
428     Map = isl_map_add_constraint(Map, C);
429 
430     C = isl_constraint_alloc_inequality(LS);
431     C = isl_constraint_set_coefficient_si(C, isl_dim_in, DimsArray - 1, -1);
432     C = isl_constraint_set_coefficient_si(C, isl_dim_out, DimsArray - 1, 1);
433     C = isl_constraint_set_constant_val(C, isl_val_int_from_si(Ctx, 0));
434     Map = isl_map_add_constraint(Map, C);
435     AccessRelation = isl_map_apply_range(AccessRelation, Map);
436   }
437 
438   isl_space_free(ArraySpace);
439 
440   assumeNoOutOfBound();
441 }
442 
443 const std::string
444 MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
445   switch (RT) {
446   case MemoryAccess::RT_NONE:
447     llvm_unreachable("Requested a reduction operator string for a memory "
448                      "access which isn't a reduction");
449   case MemoryAccess::RT_ADD:
450     return "+";
451   case MemoryAccess::RT_MUL:
452     return "*";
453   case MemoryAccess::RT_BOR:
454     return "|";
455   case MemoryAccess::RT_BXOR:
456     return "^";
457   case MemoryAccess::RT_BAND:
458     return "&";
459   }
460   llvm_unreachable("Unknown reduction type");
461   return "";
462 }
463 
464 /// Return the reduction type for a given binary operator.
465 static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp,
466                                                     const Instruction *Load) {
467   if (!BinOp)
468     return MemoryAccess::RT_NONE;
469   switch (BinOp->getOpcode()) {
470   case Instruction::FAdd:
471     if (!BinOp->hasUnsafeAlgebra())
472       return MemoryAccess::RT_NONE;
473   // Fall through
474   case Instruction::Add:
475     return MemoryAccess::RT_ADD;
476   case Instruction::Or:
477     return MemoryAccess::RT_BOR;
478   case Instruction::Xor:
479     return MemoryAccess::RT_BXOR;
480   case Instruction::And:
481     return MemoryAccess::RT_BAND;
482   case Instruction::FMul:
483     if (!BinOp->hasUnsafeAlgebra())
484       return MemoryAccess::RT_NONE;
485   // Fall through
486   case Instruction::Mul:
487     if (DisableMultiplicativeReductions)
488       return MemoryAccess::RT_NONE;
489     return MemoryAccess::RT_MUL;
490   default:
491     return MemoryAccess::RT_NONE;
492   }
493 }
494 
495 MemoryAccess::~MemoryAccess() {
496   isl_id_free(Id);
497   isl_set_free(InvalidDomain);
498   isl_map_free(AccessRelation);
499   isl_map_free(NewAccessRelation);
500 }
501 
502 const ScopArrayInfo *MemoryAccess::getOriginalScopArrayInfo() const {
503   isl_id *ArrayId = getArrayId();
504   void *User = isl_id_get_user(ArrayId);
505   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
506   isl_id_free(ArrayId);
507   return SAI;
508 }
509 
510 const ScopArrayInfo *MemoryAccess::getLatestScopArrayInfo() const {
511   isl_id *ArrayId = getLatestArrayId();
512   void *User = isl_id_get_user(ArrayId);
513   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
514   isl_id_free(ArrayId);
515   return SAI;
516 }
517 
518 __isl_give isl_id *MemoryAccess::getOriginalArrayId() const {
519   return isl_map_get_tuple_id(AccessRelation, isl_dim_out);
520 }
521 
522 __isl_give isl_id *MemoryAccess::getLatestArrayId() const {
523   if (!hasNewAccessRelation())
524     return getOriginalArrayId();
525   return isl_map_get_tuple_id(NewAccessRelation, isl_dim_out);
526 }
527 
528 __isl_give isl_map *MemoryAccess::getAddressFunction() const {
529   return isl_map_lexmin(getAccessRelation());
530 }
531 
532 __isl_give isl_pw_multi_aff *MemoryAccess::applyScheduleToAccessRelation(
533     __isl_take isl_union_map *USchedule) const {
534   isl_map *Schedule, *ScheduledAccRel;
535   isl_union_set *UDomain;
536 
537   UDomain = isl_union_set_from_set(getStatement()->getDomain());
538   USchedule = isl_union_map_intersect_domain(USchedule, UDomain);
539   Schedule = isl_map_from_union_map(USchedule);
540   ScheduledAccRel = isl_map_apply_domain(getAddressFunction(), Schedule);
541   return isl_pw_multi_aff_from_map(ScheduledAccRel);
542 }
543 
544 __isl_give isl_map *MemoryAccess::getOriginalAccessRelation() const {
545   return isl_map_copy(AccessRelation);
546 }
547 
548 std::string MemoryAccess::getOriginalAccessRelationStr() const {
549   return stringFromIslObj(AccessRelation);
550 }
551 
552 __isl_give isl_space *MemoryAccess::getOriginalAccessRelationSpace() const {
553   return isl_map_get_space(AccessRelation);
554 }
555 
556 __isl_give isl_map *MemoryAccess::getNewAccessRelation() const {
557   return isl_map_copy(NewAccessRelation);
558 }
559 
560 std::string MemoryAccess::getNewAccessRelationStr() const {
561   return stringFromIslObj(NewAccessRelation);
562 }
563 
564 __isl_give isl_basic_map *
565 MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
566   isl_space *Space = isl_space_set_alloc(Statement->getIslCtx(), 0, 1);
567   Space = isl_space_align_params(Space, Statement->getDomainSpace());
568 
569   return isl_basic_map_from_domain_and_range(
570       isl_basic_set_universe(Statement->getDomainSpace()),
571       isl_basic_set_universe(Space));
572 }
573 
574 // Formalize no out-of-bound access assumption
575 //
576 // When delinearizing array accesses we optimistically assume that the
577 // delinearized accesses do not access out of bound locations (the subscript
578 // expression of each array evaluates for each statement instance that is
579 // executed to a value that is larger than zero and strictly smaller than the
580 // size of the corresponding dimension). The only exception is the outermost
581 // dimension for which we do not need to assume any upper bound.  At this point
582 // we formalize this assumption to ensure that at code generation time the
583 // relevant run-time checks can be generated.
584 //
585 // To find the set of constraints necessary to avoid out of bound accesses, we
586 // first build the set of data locations that are not within array bounds. We
587 // then apply the reverse access relation to obtain the set of iterations that
588 // may contain invalid accesses and reduce this set of iterations to the ones
589 // that are actually executed by intersecting them with the domain of the
590 // statement. If we now project out all loop dimensions, we obtain a set of
591 // parameters that may cause statement instances to be executed that may
592 // possibly yield out of bound memory accesses. The complement of these
593 // constraints is the set of constraints that needs to be assumed to ensure such
594 // statement instances are never executed.
595 void MemoryAccess::assumeNoOutOfBound() {
596   auto *SAI = getScopArrayInfo();
597   isl_space *Space = isl_space_range(getOriginalAccessRelationSpace());
598   isl_set *Outside = isl_set_empty(isl_space_copy(Space));
599   for (int i = 1, Size = isl_space_dim(Space, isl_dim_set); i < Size; ++i) {
600     isl_local_space *LS = isl_local_space_from_space(isl_space_copy(Space));
601     isl_pw_aff *Var =
602         isl_pw_aff_var_on_domain(isl_local_space_copy(LS), isl_dim_set, i);
603     isl_pw_aff *Zero = isl_pw_aff_zero_on_domain(LS);
604 
605     isl_set *DimOutside;
606 
607     DimOutside = isl_pw_aff_lt_set(isl_pw_aff_copy(Var), Zero);
608     isl_pw_aff *SizeE = SAI->getDimensionSizePw(i);
609     SizeE = isl_pw_aff_add_dims(SizeE, isl_dim_in,
610                                 isl_space_dim(Space, isl_dim_set));
611     SizeE = isl_pw_aff_set_tuple_id(SizeE, isl_dim_in,
612                                     isl_space_get_tuple_id(Space, isl_dim_set));
613 
614     DimOutside = isl_set_union(DimOutside, isl_pw_aff_le_set(SizeE, Var));
615 
616     Outside = isl_set_union(Outside, DimOutside);
617   }
618 
619   Outside = isl_set_apply(Outside, isl_map_reverse(getAccessRelation()));
620   Outside = isl_set_intersect(Outside, Statement->getDomain());
621   Outside = isl_set_params(Outside);
622 
623   // Remove divs to avoid the construction of overly complicated assumptions.
624   // Doing so increases the set of parameter combinations that are assumed to
625   // not appear. This is always save, but may make the resulting run-time check
626   // bail out more often than strictly necessary.
627   Outside = isl_set_remove_divs(Outside);
628   Outside = isl_set_complement(Outside);
629   const auto &Loc = getAccessInstruction()
630                         ? getAccessInstruction()->getDebugLoc()
631                         : DebugLoc();
632   Statement->getParent()->recordAssumption(INBOUNDS, Outside, Loc,
633                                            AS_ASSUMPTION);
634   isl_space_free(Space);
635 }
636 
637 void MemoryAccess::buildMemIntrinsicAccessRelation() {
638   assert(isa<MemIntrinsic>(getAccessInstruction()));
639   assert(Subscripts.size() == 2 && Sizes.size() == 0);
640 
641   auto *SubscriptPWA = getPwAff(Subscripts[0]);
642   auto *SubscriptMap = isl_map_from_pw_aff(SubscriptPWA);
643 
644   isl_map *LengthMap;
645   if (Subscripts[1] == nullptr) {
646     LengthMap = isl_map_universe(isl_map_get_space(SubscriptMap));
647   } else {
648     auto *LengthPWA = getPwAff(Subscripts[1]);
649     LengthMap = isl_map_from_pw_aff(LengthPWA);
650     auto *RangeSpace = isl_space_range(isl_map_get_space(LengthMap));
651     LengthMap = isl_map_apply_range(LengthMap, isl_map_lex_gt(RangeSpace));
652   }
653   LengthMap = isl_map_lower_bound_si(LengthMap, isl_dim_out, 0, 0);
654   LengthMap = isl_map_align_params(LengthMap, isl_map_get_space(SubscriptMap));
655   SubscriptMap =
656       isl_map_align_params(SubscriptMap, isl_map_get_space(LengthMap));
657   LengthMap = isl_map_sum(LengthMap, SubscriptMap);
658   AccessRelation = isl_map_set_tuple_id(LengthMap, isl_dim_in,
659                                         getStatement()->getDomainId());
660 }
661 
662 void MemoryAccess::computeBoundsOnAccessRelation(unsigned ElementSize) {
663   ScalarEvolution *SE = Statement->getParent()->getSE();
664 
665   auto MAI = MemAccInst(getAccessInstruction());
666   if (isa<MemIntrinsic>(MAI))
667     return;
668 
669   Value *Ptr = MAI.getPointerOperand();
670   if (!Ptr || !SE->isSCEVable(Ptr->getType()))
671     return;
672 
673   auto *PtrSCEV = SE->getSCEV(Ptr);
674   if (isa<SCEVCouldNotCompute>(PtrSCEV))
675     return;
676 
677   auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
678   if (BasePtrSCEV && !isa<SCEVCouldNotCompute>(BasePtrSCEV))
679     PtrSCEV = SE->getMinusSCEV(PtrSCEV, BasePtrSCEV);
680 
681   const ConstantRange &Range = SE->getSignedRange(PtrSCEV);
682   if (Range.isFullSet())
683     return;
684 
685   bool isWrapping = Range.isSignWrappedSet();
686   unsigned BW = Range.getBitWidth();
687   const auto One = APInt(BW, 1);
688   const auto LB = isWrapping ? Range.getLower() : Range.getSignedMin();
689   const auto UB = isWrapping ? (Range.getUpper() - One) : Range.getSignedMax();
690 
691   auto Min = LB.sdiv(APInt(BW, ElementSize));
692   auto Max = UB.sdiv(APInt(BW, ElementSize)) + One;
693 
694   isl_set *AccessRange = isl_map_range(isl_map_copy(AccessRelation));
695   AccessRange =
696       addRangeBoundsToSet(AccessRange, ConstantRange(Min, Max), 0, isl_dim_set);
697   AccessRelation = isl_map_intersect_range(AccessRelation, AccessRange);
698 }
699 
700 __isl_give isl_map *MemoryAccess::foldAccess(__isl_take isl_map *AccessRelation,
701                                              ScopStmt *Statement) {
702   int Size = Subscripts.size();
703 
704   for (int i = Size - 2; i >= 0; --i) {
705     isl_space *Space;
706     isl_map *MapOne, *MapTwo;
707     isl_pw_aff *DimSize = getPwAff(Sizes[i]);
708 
709     isl_space *SpaceSize = isl_pw_aff_get_space(DimSize);
710     isl_pw_aff_free(DimSize);
711     isl_id *ParamId = isl_space_get_dim_id(SpaceSize, isl_dim_param, 0);
712 
713     Space = isl_map_get_space(AccessRelation);
714     Space = isl_space_map_from_set(isl_space_range(Space));
715     Space = isl_space_align_params(Space, SpaceSize);
716 
717     int ParamLocation = isl_space_find_dim_by_id(Space, isl_dim_param, ParamId);
718     isl_id_free(ParamId);
719 
720     MapOne = isl_map_universe(isl_space_copy(Space));
721     for (int j = 0; j < Size; ++j)
722       MapOne = isl_map_equate(MapOne, isl_dim_in, j, isl_dim_out, j);
723     MapOne = isl_map_lower_bound_si(MapOne, isl_dim_in, i + 1, 0);
724 
725     MapTwo = isl_map_universe(isl_space_copy(Space));
726     for (int j = 0; j < Size; ++j)
727       if (j < i || j > i + 1)
728         MapTwo = isl_map_equate(MapTwo, isl_dim_in, j, isl_dim_out, j);
729 
730     isl_local_space *LS = isl_local_space_from_space(Space);
731     isl_constraint *C;
732     C = isl_equality_alloc(isl_local_space_copy(LS));
733     C = isl_constraint_set_constant_si(C, -1);
734     C = isl_constraint_set_coefficient_si(C, isl_dim_in, i, 1);
735     C = isl_constraint_set_coefficient_si(C, isl_dim_out, i, -1);
736     MapTwo = isl_map_add_constraint(MapTwo, C);
737     C = isl_equality_alloc(LS);
738     C = isl_constraint_set_coefficient_si(C, isl_dim_in, i + 1, 1);
739     C = isl_constraint_set_coefficient_si(C, isl_dim_out, i + 1, -1);
740     C = isl_constraint_set_coefficient_si(C, isl_dim_param, ParamLocation, 1);
741     MapTwo = isl_map_add_constraint(MapTwo, C);
742     MapTwo = isl_map_upper_bound_si(MapTwo, isl_dim_in, i + 1, -1);
743 
744     MapOne = isl_map_union(MapOne, MapTwo);
745     AccessRelation = isl_map_apply_range(AccessRelation, MapOne);
746   }
747   return AccessRelation;
748 }
749 
750 /// Check if @p Expr is divisible by @p Size.
751 static bool isDivisible(const SCEV *Expr, unsigned Size, ScalarEvolution &SE) {
752   assert(Size != 0);
753   if (Size == 1)
754     return true;
755 
756   // Only one factor needs to be divisible.
757   if (auto *MulExpr = dyn_cast<SCEVMulExpr>(Expr)) {
758     for (auto *FactorExpr : MulExpr->operands())
759       if (isDivisible(FactorExpr, Size, SE))
760         return true;
761     return false;
762   }
763 
764   // For other n-ary expressions (Add, AddRec, Max,...) all operands need
765   // to be divisble.
766   if (auto *NAryExpr = dyn_cast<SCEVNAryExpr>(Expr)) {
767     for (auto *OpExpr : NAryExpr->operands())
768       if (!isDivisible(OpExpr, Size, SE))
769         return false;
770     return true;
771   }
772 
773   auto *SizeSCEV = SE.getConstant(Expr->getType(), Size);
774   auto *UDivSCEV = SE.getUDivExpr(Expr, SizeSCEV);
775   auto *MulSCEV = SE.getMulExpr(UDivSCEV, SizeSCEV);
776   return MulSCEV == Expr;
777 }
778 
779 void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) {
780   assert(!AccessRelation && "AccessReltation already built");
781 
782   // Initialize the invalid domain which describes all iterations for which the
783   // access relation is not modeled correctly.
784   auto *StmtInvalidDomain = getStatement()->getInvalidDomain();
785   InvalidDomain = isl_set_empty(isl_set_get_space(StmtInvalidDomain));
786   isl_set_free(StmtInvalidDomain);
787 
788   isl_ctx *Ctx = isl_id_get_ctx(Id);
789   isl_id *BaseAddrId = SAI->getBasePtrId();
790 
791   if (!isAffine()) {
792     if (isa<MemIntrinsic>(getAccessInstruction()))
793       buildMemIntrinsicAccessRelation();
794 
795     // We overapproximate non-affine accesses with a possible access to the
796     // whole array. For read accesses it does not make a difference, if an
797     // access must or may happen. However, for write accesses it is important to
798     // differentiate between writes that must happen and writes that may happen.
799     if (!AccessRelation)
800       AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
801 
802     AccessRelation =
803         isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
804     return;
805   }
806 
807   isl_space *Space = isl_space_alloc(Ctx, 0, Statement->getNumIterators(), 0);
808   AccessRelation = isl_map_universe(Space);
809 
810   for (int i = 0, Size = Subscripts.size(); i < Size; ++i) {
811     isl_pw_aff *Affine = getPwAff(Subscripts[i]);
812     isl_map *SubscriptMap = isl_map_from_pw_aff(Affine);
813     AccessRelation = isl_map_flat_range_product(AccessRelation, SubscriptMap);
814   }
815 
816   if (Sizes.size() >= 1 && !isa<SCEVConstant>(Sizes[0]))
817     AccessRelation = foldAccess(AccessRelation, Statement);
818 
819   Space = Statement->getDomainSpace();
820   AccessRelation = isl_map_set_tuple_id(
821       AccessRelation, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
822   AccessRelation =
823       isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
824 
825   AccessRelation = isl_map_gist_domain(AccessRelation, Statement->getDomain());
826   isl_space_free(Space);
827 }
828 
829 MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
830                            AccessType AccType, Value *BaseAddress,
831                            Type *ElementType, bool Affine,
832                            ArrayRef<const SCEV *> Subscripts,
833                            ArrayRef<const SCEV *> Sizes, Value *AccessValue,
834                            ScopArrayInfo::MemoryKind Kind, StringRef BaseName)
835     : Kind(Kind), AccType(AccType), RedType(RT_NONE), Statement(Stmt),
836       InvalidDomain(nullptr), BaseAddr(BaseAddress), BaseName(BaseName),
837       ElementType(ElementType), Sizes(Sizes.begin(), Sizes.end()),
838       AccessInstruction(AccessInst), AccessValue(AccessValue), IsAffine(Affine),
839       Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(nullptr),
840       NewAccessRelation(nullptr) {
841   static const std::string TypeStrings[] = {"", "_Read", "_Write", "_MayWrite"};
842   const std::string Access = TypeStrings[AccType] + utostr(Stmt->size()) + "_";
843 
844   std::string IdName =
845       getIslCompatibleName(Stmt->getBaseName(), Access, BaseName);
846   Id = isl_id_alloc(Stmt->getParent()->getIslCtx(), IdName.c_str(), this);
847 }
848 
849 void MemoryAccess::realignParams() {
850   auto *Ctx = Statement->getParent()->getContext();
851   InvalidDomain = isl_set_gist_params(InvalidDomain, isl_set_copy(Ctx));
852   AccessRelation = isl_map_gist_params(AccessRelation, Ctx);
853 }
854 
855 const std::string MemoryAccess::getReductionOperatorStr() const {
856   return MemoryAccess::getReductionOperatorStr(getReductionType());
857 }
858 
859 __isl_give isl_id *MemoryAccess::getId() const { return isl_id_copy(Id); }
860 
861 raw_ostream &polly::operator<<(raw_ostream &OS,
862                                MemoryAccess::ReductionType RT) {
863   if (RT == MemoryAccess::RT_NONE)
864     OS << "NONE";
865   else
866     OS << MemoryAccess::getReductionOperatorStr(RT);
867   return OS;
868 }
869 
870 void MemoryAccess::print(raw_ostream &OS) const {
871   switch (AccType) {
872   case READ:
873     OS.indent(12) << "ReadAccess :=\t";
874     break;
875   case MUST_WRITE:
876     OS.indent(12) << "MustWriteAccess :=\t";
877     break;
878   case MAY_WRITE:
879     OS.indent(12) << "MayWriteAccess :=\t";
880     break;
881   }
882   OS << "[Reduction Type: " << getReductionType() << "] ";
883   OS << "[Scalar: " << isScalarKind() << "]\n";
884   OS.indent(16) << getOriginalAccessRelationStr() << ";\n";
885   if (hasNewAccessRelation())
886     OS.indent(11) << "new: " << getNewAccessRelationStr() << ";\n";
887 }
888 
889 void MemoryAccess::dump() const { print(errs()); }
890 
891 __isl_give isl_pw_aff *MemoryAccess::getPwAff(const SCEV *E) {
892   auto *Stmt = getStatement();
893   PWACtx PWAC = Stmt->getParent()->getPwAff(E, Stmt->getEntryBlock());
894   isl_set *StmtDom = isl_set_reset_tuple_id(getStatement()->getDomain());
895   isl_set *NewInvalidDom = isl_set_intersect(StmtDom, PWAC.second);
896   InvalidDomain = isl_set_union(InvalidDomain, NewInvalidDom);
897   return PWAC.first;
898 }
899 
900 // Create a map in the size of the provided set domain, that maps from the
901 // one element of the provided set domain to another element of the provided
902 // set domain.
903 // The mapping is limited to all points that are equal in all but the last
904 // dimension and for which the last dimension of the input is strict smaller
905 // than the last dimension of the output.
906 //
907 //   getEqualAndLarger(set[i0, i1, ..., iX]):
908 //
909 //   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
910 //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
911 //
912 static isl_map *getEqualAndLarger(__isl_take isl_space *setDomain) {
913   isl_space *Space = isl_space_map_from_set(setDomain);
914   isl_map *Map = isl_map_universe(Space);
915   unsigned lastDimension = isl_map_dim(Map, isl_dim_in) - 1;
916 
917   // Set all but the last dimension to be equal for the input and output
918   //
919   //   input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
920   //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
921   for (unsigned i = 0; i < lastDimension; ++i)
922     Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
923 
924   // Set the last dimension of the input to be strict smaller than the
925   // last dimension of the output.
926   //
927   //   input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
928   Map = isl_map_order_lt(Map, isl_dim_in, lastDimension, isl_dim_out,
929                          lastDimension);
930   return Map;
931 }
932 
933 __isl_give isl_set *
934 MemoryAccess::getStride(__isl_take const isl_map *Schedule) const {
935   isl_map *S = const_cast<isl_map *>(Schedule);
936   isl_map *AccessRelation = getAccessRelation();
937   isl_space *Space = isl_space_range(isl_map_get_space(S));
938   isl_map *NextScatt = getEqualAndLarger(Space);
939 
940   S = isl_map_reverse(S);
941   NextScatt = isl_map_lexmin(NextScatt);
942 
943   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(S));
944   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(AccessRelation));
945   NextScatt = isl_map_apply_domain(NextScatt, S);
946   NextScatt = isl_map_apply_domain(NextScatt, AccessRelation);
947 
948   isl_set *Deltas = isl_map_deltas(NextScatt);
949   return Deltas;
950 }
951 
952 bool MemoryAccess::isStrideX(__isl_take const isl_map *Schedule,
953                              int StrideWidth) const {
954   isl_set *Stride, *StrideX;
955   bool IsStrideX;
956 
957   Stride = getStride(Schedule);
958   StrideX = isl_set_universe(isl_set_get_space(Stride));
959   for (unsigned i = 0; i < isl_set_dim(StrideX, isl_dim_set) - 1; i++)
960     StrideX = isl_set_fix_si(StrideX, isl_dim_set, i, 0);
961   StrideX = isl_set_fix_si(StrideX, isl_dim_set,
962                            isl_set_dim(StrideX, isl_dim_set) - 1, StrideWidth);
963   IsStrideX = isl_set_is_subset(Stride, StrideX);
964 
965   isl_set_free(StrideX);
966   isl_set_free(Stride);
967 
968   return IsStrideX;
969 }
970 
971 bool MemoryAccess::isStrideZero(__isl_take const isl_map *Schedule) const {
972   return isStrideX(Schedule, 0);
973 }
974 
975 bool MemoryAccess::isStrideOne(__isl_take const isl_map *Schedule) const {
976   return isStrideX(Schedule, 1);
977 }
978 
979 void MemoryAccess::setNewAccessRelation(__isl_take isl_map *NewAccess) {
980   assert(NewAccess);
981 
982 #ifndef NDEBUG
983   // Check domain space compatibility.
984   auto *NewSpace = isl_map_get_space(NewAccess);
985   auto *NewDomainSpace = isl_space_domain(isl_space_copy(NewSpace));
986   auto *OriginalDomainSpace = getStatement()->getDomainSpace();
987   assert(isl_space_has_equal_tuples(OriginalDomainSpace, NewDomainSpace));
988   isl_space_free(NewDomainSpace);
989   isl_space_free(OriginalDomainSpace);
990 
991   // Check whether there is an access for every statement instance.
992   auto *StmtDomain = getStatement()->getDomain();
993   StmtDomain = isl_set_intersect_params(
994       StmtDomain, getStatement()->getParent()->getContext());
995   auto *NewDomain = isl_map_domain(isl_map_copy(NewAccess));
996   assert(isl_set_is_subset(StmtDomain, NewDomain) &&
997          "Partial accesses not supported");
998   isl_set_free(NewDomain);
999   isl_set_free(StmtDomain);
1000 
1001   // Check whether access dimensions correspond to number of dimensions of the
1002   // accesses array.
1003   auto *NewAccessSpace = isl_space_range(NewSpace);
1004   assert(isl_space_has_tuple_id(NewAccessSpace, isl_dim_set) &&
1005          "Must specify the array that is accessed");
1006   auto *NewArrayId = isl_space_get_tuple_id(NewAccessSpace, isl_dim_set);
1007   auto *SAI = static_cast<ScopArrayInfo *>(isl_id_get_user(NewArrayId));
1008   assert(SAI && "Must set a ScopArrayInfo");
1009   assert(!SAI->getBasePtrOriginSAI() &&
1010          "Indirect array not supported by codegen");
1011   auto Dims = SAI->getNumberOfDimensions();
1012   assert(isl_space_dim(NewAccessSpace, isl_dim_set) == Dims &&
1013          "Access dims must match array dims");
1014   isl_space_free(NewAccessSpace);
1015   isl_id_free(NewArrayId);
1016 #endif
1017 
1018   isl_map_free(NewAccessRelation);
1019   NewAccessRelation = NewAccess;
1020 }
1021 
1022 //===----------------------------------------------------------------------===//
1023 
1024 __isl_give isl_map *ScopStmt::getSchedule() const {
1025   isl_set *Domain = getDomain();
1026   if (isl_set_is_empty(Domain)) {
1027     isl_set_free(Domain);
1028     return isl_map_from_aff(
1029         isl_aff_zero_on_domain(isl_local_space_from_space(getDomainSpace())));
1030   }
1031   auto *Schedule = getParent()->getSchedule();
1032   Schedule = isl_union_map_intersect_domain(
1033       Schedule, isl_union_set_from_set(isl_set_copy(Domain)));
1034   if (isl_union_map_is_empty(Schedule)) {
1035     isl_set_free(Domain);
1036     isl_union_map_free(Schedule);
1037     return isl_map_from_aff(
1038         isl_aff_zero_on_domain(isl_local_space_from_space(getDomainSpace())));
1039   }
1040   auto *M = isl_map_from_union_map(Schedule);
1041   M = isl_map_coalesce(M);
1042   M = isl_map_gist_domain(M, Domain);
1043   M = isl_map_coalesce(M);
1044   return M;
1045 }
1046 
1047 __isl_give isl_pw_aff *ScopStmt::getPwAff(const SCEV *E, bool NonNegative) {
1048   PWACtx PWAC = getParent()->getPwAff(E, getEntryBlock(), NonNegative);
1049   InvalidDomain = isl_set_union(InvalidDomain, PWAC.second);
1050   return PWAC.first;
1051 }
1052 
1053 void ScopStmt::restrictDomain(__isl_take isl_set *NewDomain) {
1054   assert(isl_set_is_subset(NewDomain, Domain) &&
1055          "New domain is not a subset of old domain!");
1056   isl_set_free(Domain);
1057   Domain = NewDomain;
1058 }
1059 
1060 void ScopStmt::buildAccessRelations() {
1061   Scop &S = *getParent();
1062   for (MemoryAccess *Access : MemAccs) {
1063     Type *ElementType = Access->getElementType();
1064 
1065     ScopArrayInfo::MemoryKind Ty;
1066     if (Access->isPHIKind())
1067       Ty = ScopArrayInfo::MK_PHI;
1068     else if (Access->isExitPHIKind())
1069       Ty = ScopArrayInfo::MK_ExitPHI;
1070     else if (Access->isValueKind())
1071       Ty = ScopArrayInfo::MK_Value;
1072     else
1073       Ty = ScopArrayInfo::MK_Array;
1074 
1075     auto *SAI = S.getOrCreateScopArrayInfo(Access->getBaseAddr(), ElementType,
1076                                            Access->Sizes, Ty);
1077     Access->buildAccessRelation(SAI);
1078   }
1079 }
1080 
1081 void ScopStmt::addAccess(MemoryAccess *Access) {
1082   Instruction *AccessInst = Access->getAccessInstruction();
1083 
1084   if (Access->isArrayKind()) {
1085     MemoryAccessList &MAL = InstructionToAccess[AccessInst];
1086     MAL.emplace_front(Access);
1087   } else if (Access->isValueKind() && Access->isWrite()) {
1088     Instruction *AccessVal = cast<Instruction>(Access->getAccessValue());
1089     assert(Parent.getStmtFor(AccessVal) == this);
1090     assert(!ValueWrites.lookup(AccessVal));
1091 
1092     ValueWrites[AccessVal] = Access;
1093   } else if (Access->isValueKind() && Access->isRead()) {
1094     Value *AccessVal = Access->getAccessValue();
1095     assert(!ValueReads.lookup(AccessVal));
1096 
1097     ValueReads[AccessVal] = Access;
1098   } else if (Access->isAnyPHIKind() && Access->isWrite()) {
1099     PHINode *PHI = cast<PHINode>(Access->getBaseAddr());
1100     assert(!PHIWrites.lookup(PHI));
1101 
1102     PHIWrites[PHI] = Access;
1103   }
1104 
1105   MemAccs.push_back(Access);
1106 }
1107 
1108 void ScopStmt::realignParams() {
1109   for (MemoryAccess *MA : *this)
1110     MA->realignParams();
1111 
1112   auto *Ctx = Parent.getContext();
1113   InvalidDomain = isl_set_gist_params(InvalidDomain, isl_set_copy(Ctx));
1114   Domain = isl_set_gist_params(Domain, Ctx);
1115 }
1116 
1117 /// Add @p BSet to the set @p User if @p BSet is bounded.
1118 static isl_stat collectBoundedParts(__isl_take isl_basic_set *BSet,
1119                                     void *User) {
1120   isl_set **BoundedParts = static_cast<isl_set **>(User);
1121   if (isl_basic_set_is_bounded(BSet))
1122     *BoundedParts = isl_set_union(*BoundedParts, isl_set_from_basic_set(BSet));
1123   else
1124     isl_basic_set_free(BSet);
1125   return isl_stat_ok;
1126 }
1127 
1128 /// Return the bounded parts of @p S.
1129 static __isl_give isl_set *collectBoundedParts(__isl_take isl_set *S) {
1130   isl_set *BoundedParts = isl_set_empty(isl_set_get_space(S));
1131   isl_set_foreach_basic_set(S, collectBoundedParts, &BoundedParts);
1132   isl_set_free(S);
1133   return BoundedParts;
1134 }
1135 
1136 /// Compute the (un)bounded parts of @p S wrt. to dimension @p Dim.
1137 ///
1138 /// @returns A separation of @p S into first an unbounded then a bounded subset,
1139 ///          both with regards to the dimension @p Dim.
1140 static std::pair<__isl_give isl_set *, __isl_give isl_set *>
1141 partitionSetParts(__isl_take isl_set *S, unsigned Dim) {
1142 
1143   for (unsigned u = 0, e = isl_set_n_dim(S); u < e; u++)
1144     S = isl_set_lower_bound_si(S, isl_dim_set, u, 0);
1145 
1146   unsigned NumDimsS = isl_set_n_dim(S);
1147   isl_set *OnlyDimS = isl_set_copy(S);
1148 
1149   // Remove dimensions that are greater than Dim as they are not interesting.
1150   assert(NumDimsS >= Dim + 1);
1151   OnlyDimS =
1152       isl_set_project_out(OnlyDimS, isl_dim_set, Dim + 1, NumDimsS - Dim - 1);
1153 
1154   // Create artificial parametric upper bounds for dimensions smaller than Dim
1155   // as we are not interested in them.
1156   OnlyDimS = isl_set_insert_dims(OnlyDimS, isl_dim_param, 0, Dim);
1157   for (unsigned u = 0; u < Dim; u++) {
1158     isl_constraint *C = isl_inequality_alloc(
1159         isl_local_space_from_space(isl_set_get_space(OnlyDimS)));
1160     C = isl_constraint_set_coefficient_si(C, isl_dim_param, u, 1);
1161     C = isl_constraint_set_coefficient_si(C, isl_dim_set, u, -1);
1162     OnlyDimS = isl_set_add_constraint(OnlyDimS, C);
1163   }
1164 
1165   // Collect all bounded parts of OnlyDimS.
1166   isl_set *BoundedParts = collectBoundedParts(OnlyDimS);
1167 
1168   // Create the dimensions greater than Dim again.
1169   BoundedParts = isl_set_insert_dims(BoundedParts, isl_dim_set, Dim + 1,
1170                                      NumDimsS - Dim - 1);
1171 
1172   // Remove the artificial upper bound parameters again.
1173   BoundedParts = isl_set_remove_dims(BoundedParts, isl_dim_param, 0, Dim);
1174 
1175   isl_set *UnboundedParts = isl_set_subtract(S, isl_set_copy(BoundedParts));
1176   return std::make_pair(UnboundedParts, BoundedParts);
1177 }
1178 
1179 /// Set the dimension Ids from @p From in @p To.
1180 static __isl_give isl_set *setDimensionIds(__isl_keep isl_set *From,
1181                                            __isl_take isl_set *To) {
1182   for (unsigned u = 0, e = isl_set_n_dim(From); u < e; u++) {
1183     isl_id *DimId = isl_set_get_dim_id(From, isl_dim_set, u);
1184     To = isl_set_set_dim_id(To, isl_dim_set, u, DimId);
1185   }
1186   return To;
1187 }
1188 
1189 /// Create the conditions under which @p L @p Pred @p R is true.
1190 static __isl_give isl_set *buildConditionSet(ICmpInst::Predicate Pred,
1191                                              __isl_take isl_pw_aff *L,
1192                                              __isl_take isl_pw_aff *R) {
1193   switch (Pred) {
1194   case ICmpInst::ICMP_EQ:
1195     return isl_pw_aff_eq_set(L, R);
1196   case ICmpInst::ICMP_NE:
1197     return isl_pw_aff_ne_set(L, R);
1198   case ICmpInst::ICMP_SLT:
1199     return isl_pw_aff_lt_set(L, R);
1200   case ICmpInst::ICMP_SLE:
1201     return isl_pw_aff_le_set(L, R);
1202   case ICmpInst::ICMP_SGT:
1203     return isl_pw_aff_gt_set(L, R);
1204   case ICmpInst::ICMP_SGE:
1205     return isl_pw_aff_ge_set(L, R);
1206   case ICmpInst::ICMP_ULT:
1207     return isl_pw_aff_lt_set(L, R);
1208   case ICmpInst::ICMP_UGT:
1209     return isl_pw_aff_gt_set(L, R);
1210   case ICmpInst::ICMP_ULE:
1211     return isl_pw_aff_le_set(L, R);
1212   case ICmpInst::ICMP_UGE:
1213     return isl_pw_aff_ge_set(L, R);
1214   default:
1215     llvm_unreachable("Non integer predicate not supported");
1216   }
1217 }
1218 
1219 /// Create the conditions under which @p L @p Pred @p R is true.
1220 ///
1221 /// Helper function that will make sure the dimensions of the result have the
1222 /// same isl_id's as the @p Domain.
1223 static __isl_give isl_set *buildConditionSet(ICmpInst::Predicate Pred,
1224                                              __isl_take isl_pw_aff *L,
1225                                              __isl_take isl_pw_aff *R,
1226                                              __isl_keep isl_set *Domain) {
1227   isl_set *ConsequenceCondSet = buildConditionSet(Pred, L, R);
1228   return setDimensionIds(Domain, ConsequenceCondSet);
1229 }
1230 
1231 /// Build the conditions sets for the switch @p SI in the @p Domain.
1232 ///
1233 /// This will fill @p ConditionSets with the conditions under which control
1234 /// will be moved from @p SI to its successors. Hence, @p ConditionSets will
1235 /// have as many elements as @p SI has successors.
1236 static bool
1237 buildConditionSets(ScopStmt &Stmt, SwitchInst *SI, Loop *L,
1238                    __isl_keep isl_set *Domain,
1239                    SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
1240 
1241   Value *Condition = getConditionFromTerminator(SI);
1242   assert(Condition && "No condition for switch");
1243 
1244   Scop &S = *Stmt.getParent();
1245   ScalarEvolution &SE = *S.getSE();
1246   isl_pw_aff *LHS, *RHS;
1247   LHS = Stmt.getPwAff(SE.getSCEVAtScope(Condition, L));
1248 
1249   unsigned NumSuccessors = SI->getNumSuccessors();
1250   ConditionSets.resize(NumSuccessors);
1251   for (auto &Case : SI->cases()) {
1252     unsigned Idx = Case.getSuccessorIndex();
1253     ConstantInt *CaseValue = Case.getCaseValue();
1254 
1255     RHS = Stmt.getPwAff(SE.getSCEV(CaseValue));
1256     isl_set *CaseConditionSet =
1257         buildConditionSet(ICmpInst::ICMP_EQ, isl_pw_aff_copy(LHS), RHS, Domain);
1258     ConditionSets[Idx] = isl_set_coalesce(
1259         isl_set_intersect(CaseConditionSet, isl_set_copy(Domain)));
1260   }
1261 
1262   assert(ConditionSets[0] == nullptr && "Default condition set was set");
1263   isl_set *ConditionSetUnion = isl_set_copy(ConditionSets[1]);
1264   for (unsigned u = 2; u < NumSuccessors; u++)
1265     ConditionSetUnion =
1266         isl_set_union(ConditionSetUnion, isl_set_copy(ConditionSets[u]));
1267   ConditionSets[0] = setDimensionIds(
1268       Domain, isl_set_subtract(isl_set_copy(Domain), ConditionSetUnion));
1269 
1270   isl_pw_aff_free(LHS);
1271 
1272   return true;
1273 }
1274 
1275 /// Build the conditions sets for the branch condition @p Condition in
1276 /// the @p Domain.
1277 ///
1278 /// This will fill @p ConditionSets with the conditions under which control
1279 /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
1280 /// have as many elements as @p TI has successors. If @p TI is nullptr the
1281 /// context under which @p Condition is true/false will be returned as the
1282 /// new elements of @p ConditionSets.
1283 static bool
1284 buildConditionSets(ScopStmt &Stmt, Value *Condition, TerminatorInst *TI,
1285                    Loop *L, __isl_keep isl_set *Domain,
1286                    SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
1287 
1288   Scop &S = *Stmt.getParent();
1289   isl_set *ConsequenceCondSet = nullptr;
1290   if (auto *CCond = dyn_cast<ConstantInt>(Condition)) {
1291     if (CCond->isZero())
1292       ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain));
1293     else
1294       ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain));
1295   } else if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Condition)) {
1296     auto Opcode = BinOp->getOpcode();
1297     assert(Opcode == Instruction::And || Opcode == Instruction::Or);
1298 
1299     bool Valid = buildConditionSets(Stmt, BinOp->getOperand(0), TI, L, Domain,
1300                                     ConditionSets) &&
1301                  buildConditionSets(Stmt, BinOp->getOperand(1), TI, L, Domain,
1302                                     ConditionSets);
1303     if (!Valid) {
1304       while (!ConditionSets.empty())
1305         isl_set_free(ConditionSets.pop_back_val());
1306       return false;
1307     }
1308 
1309     isl_set_free(ConditionSets.pop_back_val());
1310     isl_set *ConsCondPart0 = ConditionSets.pop_back_val();
1311     isl_set_free(ConditionSets.pop_back_val());
1312     isl_set *ConsCondPart1 = ConditionSets.pop_back_val();
1313 
1314     if (Opcode == Instruction::And)
1315       ConsequenceCondSet = isl_set_intersect(ConsCondPart0, ConsCondPart1);
1316     else
1317       ConsequenceCondSet = isl_set_union(ConsCondPart0, ConsCondPart1);
1318   } else {
1319     auto *ICond = dyn_cast<ICmpInst>(Condition);
1320     assert(ICond &&
1321            "Condition of exiting branch was neither constant nor ICmp!");
1322 
1323     ScalarEvolution &SE = *S.getSE();
1324     isl_pw_aff *LHS, *RHS;
1325     // For unsigned comparisons we assumed the signed bit of neither operand
1326     // to be set. The comparison is equal to a signed comparison under this
1327     // assumption.
1328     bool NonNeg = ICond->isUnsigned();
1329     LHS = Stmt.getPwAff(SE.getSCEVAtScope(ICond->getOperand(0), L), NonNeg);
1330     RHS = Stmt.getPwAff(SE.getSCEVAtScope(ICond->getOperand(1), L), NonNeg);
1331     ConsequenceCondSet =
1332         buildConditionSet(ICond->getPredicate(), LHS, RHS, Domain);
1333   }
1334 
1335   // If no terminator was given we are only looking for parameter constraints
1336   // under which @p Condition is true/false.
1337   if (!TI)
1338     ConsequenceCondSet = isl_set_params(ConsequenceCondSet);
1339   assert(ConsequenceCondSet);
1340   ConsequenceCondSet = isl_set_coalesce(
1341       isl_set_intersect(ConsequenceCondSet, isl_set_copy(Domain)));
1342 
1343   isl_set *AlternativeCondSet = nullptr;
1344   bool TooComplex =
1345       isl_set_n_basic_set(ConsequenceCondSet) >= MaxDisjunctionsInDomain;
1346 
1347   if (!TooComplex) {
1348     AlternativeCondSet = isl_set_subtract(isl_set_copy(Domain),
1349                                           isl_set_copy(ConsequenceCondSet));
1350     TooComplex =
1351         isl_set_n_basic_set(AlternativeCondSet) >= MaxDisjunctionsInDomain;
1352   }
1353 
1354   if (TooComplex) {
1355     S.invalidate(COMPLEXITY, TI ? TI->getDebugLoc() : DebugLoc());
1356     isl_set_free(AlternativeCondSet);
1357     isl_set_free(ConsequenceCondSet);
1358     return false;
1359   }
1360 
1361   ConditionSets.push_back(ConsequenceCondSet);
1362   ConditionSets.push_back(isl_set_coalesce(AlternativeCondSet));
1363 
1364   return true;
1365 }
1366 
1367 /// Build the conditions sets for the terminator @p TI in the @p Domain.
1368 ///
1369 /// This will fill @p ConditionSets with the conditions under which control
1370 /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
1371 /// have as many elements as @p TI has successors.
1372 static bool
1373 buildConditionSets(ScopStmt &Stmt, TerminatorInst *TI, Loop *L,
1374                    __isl_keep isl_set *Domain,
1375                    SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
1376 
1377   if (SwitchInst *SI = dyn_cast<SwitchInst>(TI))
1378     return buildConditionSets(Stmt, SI, L, Domain, ConditionSets);
1379 
1380   assert(isa<BranchInst>(TI) && "Terminator was neither branch nor switch.");
1381 
1382   if (TI->getNumSuccessors() == 1) {
1383     ConditionSets.push_back(isl_set_copy(Domain));
1384     return true;
1385   }
1386 
1387   Value *Condition = getConditionFromTerminator(TI);
1388   assert(Condition && "No condition for Terminator");
1389 
1390   return buildConditionSets(Stmt, Condition, TI, L, Domain, ConditionSets);
1391 }
1392 
1393 void ScopStmt::buildDomain() {
1394   isl_id *Id = isl_id_alloc(getIslCtx(), getBaseName(), this);
1395 
1396   Domain = getParent()->getDomainConditions(this);
1397   Domain = isl_set_set_tuple_id(Domain, Id);
1398 }
1399 
1400 void ScopStmt::collectSurroundingLoops() {
1401   for (unsigned u = 0, e = isl_set_n_dim(Domain); u < e; u++) {
1402     isl_id *DimId = isl_set_get_dim_id(Domain, isl_dim_set, u);
1403     NestLoops.push_back(static_cast<Loop *>(isl_id_get_user(DimId)));
1404     isl_id_free(DimId);
1405   }
1406 }
1407 
1408 ScopStmt::ScopStmt(Scop &parent, Region &R)
1409     : Parent(parent), InvalidDomain(nullptr), Domain(nullptr), BB(nullptr),
1410       R(&R), Build(nullptr) {
1411 
1412   BaseName = getIslCompatibleName("Stmt_", R.getNameStr(), "");
1413 }
1414 
1415 ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb)
1416     : Parent(parent), InvalidDomain(nullptr), Domain(nullptr), BB(&bb),
1417       R(nullptr), Build(nullptr) {
1418 
1419   BaseName = getIslCompatibleName("Stmt_", &bb, "");
1420 }
1421 
1422 void ScopStmt::init(LoopInfo &LI) {
1423   assert(!Domain && "init must be called only once");
1424 
1425   buildDomain();
1426   collectSurroundingLoops();
1427   buildAccessRelations();
1428 
1429   if (DetectReductions)
1430     checkForReductions();
1431 }
1432 
1433 /// Collect loads which might form a reduction chain with @p StoreMA.
1434 ///
1435 /// Check if the stored value for @p StoreMA is a binary operator with one or
1436 /// two loads as operands. If the binary operand is commutative & associative,
1437 /// used only once (by @p StoreMA) and its load operands are also used only
1438 /// once, we have found a possible reduction chain. It starts at an operand
1439 /// load and includes the binary operator and @p StoreMA.
1440 ///
1441 /// Note: We allow only one use to ensure the load and binary operator cannot
1442 ///       escape this block or into any other store except @p StoreMA.
1443 void ScopStmt::collectCandiateReductionLoads(
1444     MemoryAccess *StoreMA, SmallVectorImpl<MemoryAccess *> &Loads) {
1445   auto *Store = dyn_cast<StoreInst>(StoreMA->getAccessInstruction());
1446   if (!Store)
1447     return;
1448 
1449   // Skip if there is not one binary operator between the load and the store
1450   auto *BinOp = dyn_cast<BinaryOperator>(Store->getValueOperand());
1451   if (!BinOp)
1452     return;
1453 
1454   // Skip if the binary operators has multiple uses
1455   if (BinOp->getNumUses() != 1)
1456     return;
1457 
1458   // Skip if the opcode of the binary operator is not commutative/associative
1459   if (!BinOp->isCommutative() || !BinOp->isAssociative())
1460     return;
1461 
1462   // Skip if the binary operator is outside the current SCoP
1463   if (BinOp->getParent() != Store->getParent())
1464     return;
1465 
1466   // Skip if it is a multiplicative reduction and we disabled them
1467   if (DisableMultiplicativeReductions &&
1468       (BinOp->getOpcode() == Instruction::Mul ||
1469        BinOp->getOpcode() == Instruction::FMul))
1470     return;
1471 
1472   // Check the binary operator operands for a candidate load
1473   auto *PossibleLoad0 = dyn_cast<LoadInst>(BinOp->getOperand(0));
1474   auto *PossibleLoad1 = dyn_cast<LoadInst>(BinOp->getOperand(1));
1475   if (!PossibleLoad0 && !PossibleLoad1)
1476     return;
1477 
1478   // A load is only a candidate if it cannot escape (thus has only this use)
1479   if (PossibleLoad0 && PossibleLoad0->getNumUses() == 1)
1480     if (PossibleLoad0->getParent() == Store->getParent())
1481       Loads.push_back(&getArrayAccessFor(PossibleLoad0));
1482   if (PossibleLoad1 && PossibleLoad1->getNumUses() == 1)
1483     if (PossibleLoad1->getParent() == Store->getParent())
1484       Loads.push_back(&getArrayAccessFor(PossibleLoad1));
1485 }
1486 
1487 /// Check for reductions in this ScopStmt.
1488 ///
1489 /// Iterate over all store memory accesses and check for valid binary reduction
1490 /// like chains. For all candidates we check if they have the same base address
1491 /// and there are no other accesses which overlap with them. The base address
1492 /// check rules out impossible reductions candidates early. The overlap check,
1493 /// together with the "only one user" check in collectCandiateReductionLoads,
1494 /// guarantees that none of the intermediate results will escape during
1495 /// execution of the loop nest. We basically check here that no other memory
1496 /// access can access the same memory as the potential reduction.
1497 void ScopStmt::checkForReductions() {
1498   SmallVector<MemoryAccess *, 2> Loads;
1499   SmallVector<std::pair<MemoryAccess *, MemoryAccess *>, 4> Candidates;
1500 
1501   // First collect candidate load-store reduction chains by iterating over all
1502   // stores and collecting possible reduction loads.
1503   for (MemoryAccess *StoreMA : MemAccs) {
1504     if (StoreMA->isRead())
1505       continue;
1506 
1507     Loads.clear();
1508     collectCandiateReductionLoads(StoreMA, Loads);
1509     for (MemoryAccess *LoadMA : Loads)
1510       Candidates.push_back(std::make_pair(LoadMA, StoreMA));
1511   }
1512 
1513   // Then check each possible candidate pair.
1514   for (const auto &CandidatePair : Candidates) {
1515     bool Valid = true;
1516     isl_map *LoadAccs = CandidatePair.first->getAccessRelation();
1517     isl_map *StoreAccs = CandidatePair.second->getAccessRelation();
1518 
1519     // Skip those with obviously unequal base addresses.
1520     if (!isl_map_has_equal_space(LoadAccs, StoreAccs)) {
1521       isl_map_free(LoadAccs);
1522       isl_map_free(StoreAccs);
1523       continue;
1524     }
1525 
1526     // And check if the remaining for overlap with other memory accesses.
1527     isl_map *AllAccsRel = isl_map_union(LoadAccs, StoreAccs);
1528     AllAccsRel = isl_map_intersect_domain(AllAccsRel, getDomain());
1529     isl_set *AllAccs = isl_map_range(AllAccsRel);
1530 
1531     for (MemoryAccess *MA : MemAccs) {
1532       if (MA == CandidatePair.first || MA == CandidatePair.second)
1533         continue;
1534 
1535       isl_map *AccRel =
1536           isl_map_intersect_domain(MA->getAccessRelation(), getDomain());
1537       isl_set *Accs = isl_map_range(AccRel);
1538 
1539       if (isl_set_has_equal_space(AllAccs, Accs)) {
1540         isl_set *OverlapAccs = isl_set_intersect(Accs, isl_set_copy(AllAccs));
1541         Valid = Valid && isl_set_is_empty(OverlapAccs);
1542         isl_set_free(OverlapAccs);
1543       } else {
1544         isl_set_free(Accs);
1545       }
1546     }
1547 
1548     isl_set_free(AllAccs);
1549     if (!Valid)
1550       continue;
1551 
1552     const LoadInst *Load =
1553         dyn_cast<const LoadInst>(CandidatePair.first->getAccessInstruction());
1554     MemoryAccess::ReductionType RT =
1555         getReductionType(dyn_cast<BinaryOperator>(Load->user_back()), Load);
1556 
1557     // If no overlapping access was found we mark the load and store as
1558     // reduction like.
1559     CandidatePair.first->markAsReductionLike(RT);
1560     CandidatePair.second->markAsReductionLike(RT);
1561   }
1562 }
1563 
1564 std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
1565 
1566 std::string ScopStmt::getScheduleStr() const {
1567   auto *S = getSchedule();
1568   auto Str = stringFromIslObj(S);
1569   isl_map_free(S);
1570   return Str;
1571 }
1572 
1573 void ScopStmt::setInvalidDomain(__isl_take isl_set *ID) {
1574   isl_set_free(InvalidDomain);
1575   InvalidDomain = ID;
1576 }
1577 
1578 BasicBlock *ScopStmt::getEntryBlock() const {
1579   if (isBlockStmt())
1580     return getBasicBlock();
1581   return getRegion()->getEntry();
1582 }
1583 
1584 unsigned ScopStmt::getNumIterators() const { return NestLoops.size(); }
1585 
1586 const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
1587 
1588 Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
1589   return NestLoops[Dimension];
1590 }
1591 
1592 isl_ctx *ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
1593 
1594 __isl_give isl_set *ScopStmt::getDomain() const { return isl_set_copy(Domain); }
1595 
1596 __isl_give isl_space *ScopStmt::getDomainSpace() const {
1597   return isl_set_get_space(Domain);
1598 }
1599 
1600 __isl_give isl_id *ScopStmt::getDomainId() const {
1601   return isl_set_get_tuple_id(Domain);
1602 }
1603 
1604 ScopStmt::~ScopStmt() {
1605   isl_set_free(Domain);
1606   isl_set_free(InvalidDomain);
1607 }
1608 
1609 void ScopStmt::print(raw_ostream &OS) const {
1610   OS << "\t" << getBaseName() << "\n";
1611   OS.indent(12) << "Domain :=\n";
1612 
1613   if (Domain) {
1614     OS.indent(16) << getDomainStr() << ";\n";
1615   } else
1616     OS.indent(16) << "n/a\n";
1617 
1618   OS.indent(12) << "Schedule :=\n";
1619 
1620   if (Domain) {
1621     OS.indent(16) << getScheduleStr() << ";\n";
1622   } else
1623     OS.indent(16) << "n/a\n";
1624 
1625   for (MemoryAccess *Access : MemAccs)
1626     Access->print(OS);
1627 }
1628 
1629 void ScopStmt::dump() const { print(dbgs()); }
1630 
1631 void ScopStmt::removeMemoryAccess(MemoryAccess *MA) {
1632   // Remove the memory accesses from this statement
1633   // together with all scalar accesses that were caused by it.
1634   // MK_Value READs have no access instruction, hence would not be removed by
1635   // this function. However, it is only used for invariant LoadInst accesses,
1636   // its arguments are always affine, hence synthesizable, and therefore there
1637   // are no MK_Value READ accesses to be removed.
1638   auto Predicate = [&](MemoryAccess *Acc) {
1639     return Acc->getAccessInstruction() == MA->getAccessInstruction();
1640   };
1641   MemAccs.erase(std::remove_if(MemAccs.begin(), MemAccs.end(), Predicate),
1642                 MemAccs.end());
1643   InstructionToAccess.erase(MA->getAccessInstruction());
1644 }
1645 
1646 //===----------------------------------------------------------------------===//
1647 /// Scop class implement
1648 
1649 void Scop::setContext(__isl_take isl_set *NewContext) {
1650   NewContext = isl_set_align_params(NewContext, isl_set_get_space(Context));
1651   isl_set_free(Context);
1652   Context = NewContext;
1653 }
1654 
1655 /// Remap parameter values but keep AddRecs valid wrt. invariant loads.
1656 struct SCEVSensitiveParameterRewriter
1657     : public SCEVVisitor<SCEVSensitiveParameterRewriter, const SCEV *> {
1658   ValueToValueMap &VMap;
1659   ScalarEvolution &SE;
1660 
1661 public:
1662   SCEVSensitiveParameterRewriter(ValueToValueMap &VMap, ScalarEvolution &SE)
1663       : VMap(VMap), SE(SE) {}
1664 
1665   static const SCEV *rewrite(const SCEV *E, ScalarEvolution &SE,
1666                              ValueToValueMap &VMap) {
1667     SCEVSensitiveParameterRewriter SSPR(VMap, SE);
1668     return SSPR.visit(E);
1669   }
1670 
1671   const SCEV *visit(const SCEV *E) {
1672     return SCEVVisitor<SCEVSensitiveParameterRewriter, const SCEV *>::visit(E);
1673   }
1674 
1675   const SCEV *visitConstant(const SCEVConstant *E) { return E; }
1676 
1677   const SCEV *visitTruncateExpr(const SCEVTruncateExpr *E) {
1678     return SE.getTruncateExpr(visit(E->getOperand()), E->getType());
1679   }
1680 
1681   const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *E) {
1682     return SE.getZeroExtendExpr(visit(E->getOperand()), E->getType());
1683   }
1684 
1685   const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *E) {
1686     return SE.getSignExtendExpr(visit(E->getOperand()), E->getType());
1687   }
1688 
1689   const SCEV *visitAddExpr(const SCEVAddExpr *E) {
1690     SmallVector<const SCEV *, 4> Operands;
1691     for (int i = 0, e = E->getNumOperands(); i < e; ++i)
1692       Operands.push_back(visit(E->getOperand(i)));
1693     return SE.getAddExpr(Operands);
1694   }
1695 
1696   const SCEV *visitMulExpr(const SCEVMulExpr *E) {
1697     SmallVector<const SCEV *, 4> Operands;
1698     for (int i = 0, e = E->getNumOperands(); i < e; ++i)
1699       Operands.push_back(visit(E->getOperand(i)));
1700     return SE.getMulExpr(Operands);
1701   }
1702 
1703   const SCEV *visitSMaxExpr(const SCEVSMaxExpr *E) {
1704     SmallVector<const SCEV *, 4> Operands;
1705     for (int i = 0, e = E->getNumOperands(); i < e; ++i)
1706       Operands.push_back(visit(E->getOperand(i)));
1707     return SE.getSMaxExpr(Operands);
1708   }
1709 
1710   const SCEV *visitUMaxExpr(const SCEVUMaxExpr *E) {
1711     SmallVector<const SCEV *, 4> Operands;
1712     for (int i = 0, e = E->getNumOperands(); i < e; ++i)
1713       Operands.push_back(visit(E->getOperand(i)));
1714     return SE.getUMaxExpr(Operands);
1715   }
1716 
1717   const SCEV *visitUDivExpr(const SCEVUDivExpr *E) {
1718     return SE.getUDivExpr(visit(E->getLHS()), visit(E->getRHS()));
1719   }
1720 
1721   const SCEV *visitAddRecExpr(const SCEVAddRecExpr *E) {
1722     auto *Start = visit(E->getStart());
1723     auto *AddRec = SE.getAddRecExpr(SE.getConstant(E->getType(), 0),
1724                                     visit(E->getStepRecurrence(SE)),
1725                                     E->getLoop(), SCEV::FlagAnyWrap);
1726     return SE.getAddExpr(Start, AddRec);
1727   }
1728 
1729   const SCEV *visitUnknown(const SCEVUnknown *E) {
1730     if (auto *NewValue = VMap.lookup(E->getValue()))
1731       return SE.getUnknown(NewValue);
1732     return E;
1733   }
1734 };
1735 
1736 const SCEV *Scop::getRepresentingInvariantLoadSCEV(const SCEV *S) {
1737   return SCEVSensitiveParameterRewriter::rewrite(S, *SE, InvEquivClassVMap);
1738 }
1739 
1740 void Scop::createParameterId(const SCEV *Parameter) {
1741   assert(Parameters.count(Parameter));
1742   assert(!ParameterIds.count(Parameter));
1743 
1744   std::string ParameterName = "p_" + std::to_string(getNumParams() - 1);
1745 
1746   if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
1747     Value *Val = ValueParameter->getValue();
1748 
1749     // If this parameter references a specific Value and this value has a name
1750     // we use this name as it is likely to be unique and more useful than just
1751     // a number.
1752     if (Val->hasName())
1753       ParameterName = Val->getName();
1754     else if (LoadInst *LI = dyn_cast<LoadInst>(Val)) {
1755       auto *LoadOrigin = LI->getPointerOperand()->stripInBoundsOffsets();
1756       if (LoadOrigin->hasName()) {
1757         ParameterName += "_loaded_from_";
1758         ParameterName +=
1759             LI->getPointerOperand()->stripInBoundsOffsets()->getName();
1760       }
1761     }
1762   }
1763 
1764   ParameterName = getIslCompatibleName("", ParameterName, "");
1765 
1766   auto *Id = isl_id_alloc(getIslCtx(), ParameterName.c_str(),
1767                           const_cast<void *>((const void *)Parameter));
1768   ParameterIds[Parameter] = Id;
1769 }
1770 
1771 void Scop::addParams(const ParameterSetTy &NewParameters) {
1772   for (const SCEV *Parameter : NewParameters) {
1773     // Normalize the SCEV to get the representing element for an invariant load.
1774     Parameter = extractConstantFactor(Parameter, *SE).second;
1775     Parameter = getRepresentingInvariantLoadSCEV(Parameter);
1776 
1777     if (Parameters.insert(Parameter))
1778       createParameterId(Parameter);
1779   }
1780 }
1781 
1782 __isl_give isl_id *Scop::getIdForParam(const SCEV *Parameter) {
1783   // Normalize the SCEV to get the representing element for an invariant load.
1784   Parameter = getRepresentingInvariantLoadSCEV(Parameter);
1785   return isl_id_copy(ParameterIds.lookup(Parameter));
1786 }
1787 
1788 __isl_give isl_set *
1789 Scop::addNonEmptyDomainConstraints(__isl_take isl_set *C) const {
1790   isl_set *DomainContext = isl_union_set_params(getDomains());
1791   return isl_set_intersect_params(C, DomainContext);
1792 }
1793 
1794 bool Scop::isDominatedBy(const DominatorTree &DT, BasicBlock *BB) const {
1795   return DT.dominates(BB, getEntry());
1796 }
1797 
1798 void Scop::addUserAssumptions(AssumptionCache &AC, DominatorTree &DT,
1799                               LoopInfo &LI) {
1800   auto &F = getFunction();
1801   for (auto &Assumption : AC.assumptions()) {
1802     auto *CI = dyn_cast_or_null<CallInst>(Assumption);
1803     if (!CI || CI->getNumArgOperands() != 1)
1804       continue;
1805 
1806     bool InScop = contains(CI);
1807     if (!InScop && !isDominatedBy(DT, CI->getParent()))
1808       continue;
1809 
1810     auto *L = LI.getLoopFor(CI->getParent());
1811     auto *Val = CI->getArgOperand(0);
1812     ParameterSetTy DetectedParams;
1813     if (!isAffineConstraint(Val, &R, L, *SE, DetectedParams)) {
1814       emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F,
1815                                      CI->getDebugLoc(),
1816                                      "Non-affine user assumption ignored.");
1817       continue;
1818     }
1819 
1820     // Collect all newly introduced parameters.
1821     ParameterSetTy NewParams;
1822     for (auto *Param : DetectedParams) {
1823       Param = extractConstantFactor(Param, *SE).second;
1824       Param = getRepresentingInvariantLoadSCEV(Param);
1825       if (Parameters.count(Param))
1826         continue;
1827       NewParams.insert(Param);
1828     }
1829 
1830     SmallVector<isl_set *, 2> ConditionSets;
1831     auto *TI = InScop ? CI->getParent()->getTerminator() : nullptr;
1832     auto &Stmt = InScop ? *getStmtFor(CI->getParent()) : *Stmts.begin();
1833     auto *Dom = InScop ? getDomainConditions(&Stmt) : isl_set_copy(Context);
1834     bool Valid = buildConditionSets(Stmt, Val, TI, L, Dom, ConditionSets);
1835     isl_set_free(Dom);
1836 
1837     if (!Valid)
1838       continue;
1839 
1840     isl_set *AssumptionCtx = nullptr;
1841     if (InScop) {
1842       AssumptionCtx = isl_set_complement(isl_set_params(ConditionSets[1]));
1843       isl_set_free(ConditionSets[0]);
1844     } else {
1845       AssumptionCtx = isl_set_complement(ConditionSets[1]);
1846       AssumptionCtx = isl_set_intersect(AssumptionCtx, ConditionSets[0]);
1847     }
1848 
1849     // Project out newly introduced parameters as they are not otherwise useful.
1850     if (!NewParams.empty()) {
1851       for (unsigned u = 0; u < isl_set_n_param(AssumptionCtx); u++) {
1852         auto *Id = isl_set_get_dim_id(AssumptionCtx, isl_dim_param, u);
1853         auto *Param = static_cast<const SCEV *>(isl_id_get_user(Id));
1854         isl_id_free(Id);
1855 
1856         if (!NewParams.count(Param))
1857           continue;
1858 
1859         AssumptionCtx =
1860             isl_set_project_out(AssumptionCtx, isl_dim_param, u--, 1);
1861       }
1862     }
1863 
1864     emitOptimizationRemarkAnalysis(
1865         F.getContext(), DEBUG_TYPE, F, CI->getDebugLoc(),
1866         "Use user assumption: " + stringFromIslObj(AssumptionCtx));
1867     Context = isl_set_intersect(Context, AssumptionCtx);
1868   }
1869 }
1870 
1871 void Scop::addUserContext() {
1872   if (UserContextStr.empty())
1873     return;
1874 
1875   isl_set *UserContext =
1876       isl_set_read_from_str(getIslCtx(), UserContextStr.c_str());
1877   isl_space *Space = getParamSpace();
1878   if (isl_space_dim(Space, isl_dim_param) !=
1879       isl_set_dim(UserContext, isl_dim_param)) {
1880     auto SpaceStr = isl_space_to_str(Space);
1881     errs() << "Error: the context provided in -polly-context has not the same "
1882            << "number of dimensions than the computed context. Due to this "
1883            << "mismatch, the -polly-context option is ignored. Please provide "
1884            << "the context in the parameter space: " << SpaceStr << ".\n";
1885     free(SpaceStr);
1886     isl_set_free(UserContext);
1887     isl_space_free(Space);
1888     return;
1889   }
1890 
1891   for (unsigned i = 0; i < isl_space_dim(Space, isl_dim_param); i++) {
1892     auto *NameContext = isl_set_get_dim_name(Context, isl_dim_param, i);
1893     auto *NameUserContext = isl_set_get_dim_name(UserContext, isl_dim_param, i);
1894 
1895     if (strcmp(NameContext, NameUserContext) != 0) {
1896       auto SpaceStr = isl_space_to_str(Space);
1897       errs() << "Error: the name of dimension " << i
1898              << " provided in -polly-context "
1899              << "is '" << NameUserContext << "', but the name in the computed "
1900              << "context is '" << NameContext
1901              << "'. Due to this name mismatch, "
1902              << "the -polly-context option is ignored. Please provide "
1903              << "the context in the parameter space: " << SpaceStr << ".\n";
1904       free(SpaceStr);
1905       isl_set_free(UserContext);
1906       isl_space_free(Space);
1907       return;
1908     }
1909 
1910     UserContext =
1911         isl_set_set_dim_id(UserContext, isl_dim_param, i,
1912                            isl_space_get_dim_id(Space, isl_dim_param, i));
1913   }
1914 
1915   Context = isl_set_intersect(Context, UserContext);
1916   isl_space_free(Space);
1917 }
1918 
1919 void Scop::buildInvariantEquivalenceClasses() {
1920   DenseMap<std::pair<const SCEV *, Type *>, LoadInst *> EquivClasses;
1921 
1922   const InvariantLoadsSetTy &RIL = getRequiredInvariantLoads();
1923   for (LoadInst *LInst : RIL) {
1924     const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
1925 
1926     Type *Ty = LInst->getType();
1927     LoadInst *&ClassRep = EquivClasses[std::make_pair(PointerSCEV, Ty)];
1928     if (ClassRep) {
1929       InvEquivClassVMap[LInst] = ClassRep;
1930       continue;
1931     }
1932 
1933     ClassRep = LInst;
1934     InvariantEquivClasses.emplace_back(
1935         InvariantEquivClassTy{PointerSCEV, MemoryAccessList(), nullptr, Ty});
1936   }
1937 }
1938 
1939 void Scop::buildContext() {
1940   isl_space *Space = isl_space_params_alloc(getIslCtx(), 0);
1941   Context = isl_set_universe(isl_space_copy(Space));
1942   InvalidContext = isl_set_empty(isl_space_copy(Space));
1943   AssumedContext = isl_set_universe(Space);
1944 }
1945 
1946 void Scop::addParameterBounds() {
1947   unsigned PDim = 0;
1948   for (auto *Parameter : Parameters) {
1949     ConstantRange SRange = SE->getSignedRange(Parameter);
1950     Context = addRangeBoundsToSet(Context, SRange, PDim++, isl_dim_param);
1951   }
1952 }
1953 
1954 void Scop::realignParams() {
1955   // Add all parameters into a common model.
1956   isl_space *Space = isl_space_params_alloc(getIslCtx(), ParameterIds.size());
1957 
1958   unsigned PDim = 0;
1959   for (const auto *Parameter : Parameters) {
1960     isl_id *id = getIdForParam(Parameter);
1961     Space = isl_space_set_dim_id(Space, isl_dim_param, PDim++, id);
1962   }
1963 
1964   // Align the parameters of all data structures to the model.
1965   Context = isl_set_align_params(Context, Space);
1966 
1967   // As all parameters are known add bounds to them.
1968   addParameterBounds();
1969 
1970   for (ScopStmt &Stmt : *this)
1971     Stmt.realignParams();
1972 
1973   // Simplify the schedule according to the context too.
1974   Schedule = isl_schedule_gist_domain_params(Schedule, getContext());
1975 }
1976 
1977 static __isl_give isl_set *
1978 simplifyAssumptionContext(__isl_take isl_set *AssumptionContext,
1979                           const Scop &S) {
1980   // If we modelt all blocks in the SCoP that have side effects we can simplify
1981   // the context with the constraints that are needed for anything to be
1982   // executed at all. However, if we have error blocks in the SCoP we already
1983   // assumed some parameter combinations cannot occure and removed them from the
1984   // domains, thus we cannot use the remaining domain to simplify the
1985   // assumptions.
1986   if (!S.hasErrorBlock()) {
1987     isl_set *DomainParameters = isl_union_set_params(S.getDomains());
1988     AssumptionContext =
1989         isl_set_gist_params(AssumptionContext, DomainParameters);
1990   }
1991 
1992   AssumptionContext = isl_set_gist_params(AssumptionContext, S.getContext());
1993   return AssumptionContext;
1994 }
1995 
1996 void Scop::simplifyContexts() {
1997   // The parameter constraints of the iteration domains give us a set of
1998   // constraints that need to hold for all cases where at least a single
1999   // statement iteration is executed in the whole scop. We now simplify the
2000   // assumed context under the assumption that such constraints hold and at
2001   // least a single statement iteration is executed. For cases where no
2002   // statement instances are executed, the assumptions we have taken about
2003   // the executed code do not matter and can be changed.
2004   //
2005   // WARNING: This only holds if the assumptions we have taken do not reduce
2006   //          the set of statement instances that are executed. Otherwise we
2007   //          may run into a case where the iteration domains suggest that
2008   //          for a certain set of parameter constraints no code is executed,
2009   //          but in the original program some computation would have been
2010   //          performed. In such a case, modifying the run-time conditions and
2011   //          possibly influencing the run-time check may cause certain scops
2012   //          to not be executed.
2013   //
2014   // Example:
2015   //
2016   //   When delinearizing the following code:
2017   //
2018   //     for (long i = 0; i < 100; i++)
2019   //       for (long j = 0; j < m; j++)
2020   //         A[i+p][j] = 1.0;
2021   //
2022   //   we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
2023   //   otherwise we would access out of bound data. Now, knowing that code is
2024   //   only executed for the case m >= 0, it is sufficient to assume p >= 0.
2025   AssumedContext = simplifyAssumptionContext(AssumedContext, *this);
2026   InvalidContext = isl_set_align_params(InvalidContext, getParamSpace());
2027 }
2028 
2029 /// Add the minimal/maximal access in @p Set to @p User.
2030 static isl_stat buildMinMaxAccess(__isl_take isl_set *Set, void *User) {
2031   Scop::MinMaxVectorTy *MinMaxAccesses = (Scop::MinMaxVectorTy *)User;
2032   isl_pw_multi_aff *MinPMA, *MaxPMA;
2033   isl_pw_aff *LastDimAff;
2034   isl_aff *OneAff;
2035   unsigned Pos;
2036 
2037   Set = isl_set_remove_divs(Set);
2038 
2039   if (isl_set_n_basic_set(Set) >= MaxDisjunctionsInDomain) {
2040     isl_set_free(Set);
2041     return isl_stat_error;
2042   }
2043 
2044   // Restrict the number of parameters involved in the access as the lexmin/
2045   // lexmax computation will take too long if this number is high.
2046   //
2047   // Experiments with a simple test case using an i7 4800MQ:
2048   //
2049   //  #Parameters involved | Time (in sec)
2050   //            6          |     0.01
2051   //            7          |     0.04
2052   //            8          |     0.12
2053   //            9          |     0.40
2054   //           10          |     1.54
2055   //           11          |     6.78
2056   //           12          |    30.38
2057   //
2058   if (isl_set_n_param(Set) > RunTimeChecksMaxParameters) {
2059     unsigned InvolvedParams = 0;
2060     for (unsigned u = 0, e = isl_set_n_param(Set); u < e; u++)
2061       if (isl_set_involves_dims(Set, isl_dim_param, u, 1))
2062         InvolvedParams++;
2063 
2064     if (InvolvedParams > RunTimeChecksMaxParameters) {
2065       isl_set_free(Set);
2066       return isl_stat_error;
2067     }
2068   }
2069 
2070   MinPMA = isl_set_lexmin_pw_multi_aff(isl_set_copy(Set));
2071   MaxPMA = isl_set_lexmax_pw_multi_aff(isl_set_copy(Set));
2072 
2073   MinPMA = isl_pw_multi_aff_coalesce(MinPMA);
2074   MaxPMA = isl_pw_multi_aff_coalesce(MaxPMA);
2075 
2076   // Adjust the last dimension of the maximal access by one as we want to
2077   // enclose the accessed memory region by MinPMA and MaxPMA. The pointer
2078   // we test during code generation might now point after the end of the
2079   // allocated array but we will never dereference it anyway.
2080   assert(isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) &&
2081          "Assumed at least one output dimension");
2082   Pos = isl_pw_multi_aff_dim(MaxPMA, isl_dim_out) - 1;
2083   LastDimAff = isl_pw_multi_aff_get_pw_aff(MaxPMA, Pos);
2084   OneAff = isl_aff_zero_on_domain(
2085       isl_local_space_from_space(isl_pw_aff_get_domain_space(LastDimAff)));
2086   OneAff = isl_aff_add_constant_si(OneAff, 1);
2087   LastDimAff = isl_pw_aff_add(LastDimAff, isl_pw_aff_from_aff(OneAff));
2088   MaxPMA = isl_pw_multi_aff_set_pw_aff(MaxPMA, Pos, LastDimAff);
2089 
2090   MinMaxAccesses->push_back(std::make_pair(MinPMA, MaxPMA));
2091 
2092   isl_set_free(Set);
2093   return isl_stat_ok;
2094 }
2095 
2096 static __isl_give isl_set *getAccessDomain(MemoryAccess *MA) {
2097   isl_set *Domain = MA->getStatement()->getDomain();
2098   Domain = isl_set_project_out(Domain, isl_dim_set, 0, isl_set_n_dim(Domain));
2099   return isl_set_reset_tuple_id(Domain);
2100 }
2101 
2102 /// Wrapper function to calculate minimal/maximal accesses to each array.
2103 static bool calculateMinMaxAccess(__isl_take isl_union_map *Accesses,
2104                                   __isl_take isl_union_set *Domains,
2105                                   Scop::MinMaxVectorTy &MinMaxAccesses) {
2106 
2107   Accesses = isl_union_map_intersect_domain(Accesses, Domains);
2108   isl_union_set *Locations = isl_union_map_range(Accesses);
2109   Locations = isl_union_set_coalesce(Locations);
2110   Locations = isl_union_set_detect_equalities(Locations);
2111   bool Valid = (0 == isl_union_set_foreach_set(Locations, buildMinMaxAccess,
2112                                                &MinMaxAccesses));
2113   isl_union_set_free(Locations);
2114   return Valid;
2115 }
2116 
2117 /// Helper to treat non-affine regions and basic blocks the same.
2118 ///
2119 ///{
2120 
2121 /// Return the block that is the representing block for @p RN.
2122 static inline BasicBlock *getRegionNodeBasicBlock(RegionNode *RN) {
2123   return RN->isSubRegion() ? RN->getNodeAs<Region>()->getEntry()
2124                            : RN->getNodeAs<BasicBlock>();
2125 }
2126 
2127 /// Return the @p idx'th block that is executed after @p RN.
2128 static inline BasicBlock *
2129 getRegionNodeSuccessor(RegionNode *RN, TerminatorInst *TI, unsigned idx) {
2130   if (RN->isSubRegion()) {
2131     assert(idx == 0);
2132     return RN->getNodeAs<Region>()->getExit();
2133   }
2134   return TI->getSuccessor(idx);
2135 }
2136 
2137 /// Return the smallest loop surrounding @p RN.
2138 static inline Loop *getRegionNodeLoop(RegionNode *RN, LoopInfo &LI) {
2139   if (!RN->isSubRegion())
2140     return LI.getLoopFor(RN->getNodeAs<BasicBlock>());
2141 
2142   Region *NonAffineSubRegion = RN->getNodeAs<Region>();
2143   Loop *L = LI.getLoopFor(NonAffineSubRegion->getEntry());
2144   while (L && NonAffineSubRegion->contains(L))
2145     L = L->getParentLoop();
2146   return L;
2147 }
2148 
2149 static inline unsigned getNumBlocksInRegionNode(RegionNode *RN) {
2150   if (!RN->isSubRegion())
2151     return 1;
2152 
2153   Region *R = RN->getNodeAs<Region>();
2154   return std::distance(R->block_begin(), R->block_end());
2155 }
2156 
2157 static bool containsErrorBlock(RegionNode *RN, const Region &R, LoopInfo &LI,
2158                                const DominatorTree &DT) {
2159   if (!RN->isSubRegion())
2160     return isErrorBlock(*RN->getNodeAs<BasicBlock>(), R, LI, DT);
2161   for (BasicBlock *BB : RN->getNodeAs<Region>()->blocks())
2162     if (isErrorBlock(*BB, R, LI, DT))
2163       return true;
2164   return false;
2165 }
2166 
2167 ///}
2168 
2169 static inline __isl_give isl_set *addDomainDimId(__isl_take isl_set *Domain,
2170                                                  unsigned Dim, Loop *L) {
2171   Domain = isl_set_lower_bound_si(Domain, isl_dim_set, Dim, -1);
2172   isl_id *DimId =
2173       isl_id_alloc(isl_set_get_ctx(Domain), nullptr, static_cast<void *>(L));
2174   return isl_set_set_dim_id(Domain, isl_dim_set, Dim, DimId);
2175 }
2176 
2177 __isl_give isl_set *Scop::getDomainConditions(const ScopStmt *Stmt) const {
2178   return getDomainConditions(Stmt->getEntryBlock());
2179 }
2180 
2181 __isl_give isl_set *Scop::getDomainConditions(BasicBlock *BB) const {
2182   auto DIt = DomainMap.find(BB);
2183   if (DIt != DomainMap.end())
2184     return isl_set_copy(DIt->getSecond());
2185 
2186   auto &RI = *R.getRegionInfo();
2187   auto *BBR = RI.getRegionFor(BB);
2188   while (BBR->getEntry() == BB)
2189     BBR = BBR->getParent();
2190   return getDomainConditions(BBR->getEntry());
2191 }
2192 
2193 bool Scop::buildDomains(Region *R, DominatorTree &DT, LoopInfo &LI) {
2194 
2195   bool IsOnlyNonAffineRegion = isNonAffineSubRegion(R);
2196   auto *EntryBB = R->getEntry();
2197   auto *L = IsOnlyNonAffineRegion ? nullptr : LI.getLoopFor(EntryBB);
2198   int LD = getRelativeLoopDepth(L);
2199   auto *S = isl_set_universe(isl_space_set_alloc(getIslCtx(), 0, LD + 1));
2200 
2201   while (LD-- >= 0) {
2202     S = addDomainDimId(S, LD + 1, L);
2203     L = L->getParentLoop();
2204   }
2205 
2206   // Initialize the invalid domain.
2207   auto *EntryStmt = getStmtFor(EntryBB);
2208   EntryStmt->setInvalidDomain(isl_set_empty(isl_set_get_space(S)));
2209 
2210   DomainMap[EntryBB] = S;
2211 
2212   if (IsOnlyNonAffineRegion)
2213     return !containsErrorBlock(R->getNode(), *R, LI, DT);
2214 
2215   if (!buildDomainsWithBranchConstraints(R, DT, LI))
2216     return false;
2217 
2218   if (!propagateDomainConstraints(R, DT, LI))
2219     return false;
2220 
2221   // Error blocks and blocks dominated by them have been assumed to never be
2222   // executed. Representing them in the Scop does not add any value. In fact,
2223   // it is likely to cause issues during construction of the ScopStmts. The
2224   // contents of error blocks have not been verified to be expressible and
2225   // will cause problems when building up a ScopStmt for them.
2226   // Furthermore, basic blocks dominated by error blocks may reference
2227   // instructions in the error block which, if the error block is not modeled,
2228   // can themselves not be constructed properly. To this end we will replace
2229   // the domains of error blocks and those only reachable via error blocks
2230   // with an empty set. Additionally, we will record for each block under which
2231   // parameter combination it would be reached via an error block in its
2232   // InvalidDomain. This information is needed during load hoisting.
2233   if (!propagateInvalidStmtDomains(R, DT, LI))
2234     return false;
2235 
2236   return true;
2237 }
2238 
2239 // If the loop is nonaffine/boxed, return the first non-boxed surrounding loop
2240 // for Polly. If the loop is affine, return the loop itself. Do not call
2241 // `getSCEVAtScope()` on the result of `getFirstNonBoxedLoopFor()`, as we need
2242 // to analyze the memory accesses of the nonaffine/boxed loops.
2243 static Loop *getFirstNonBoxedLoopFor(BasicBlock *BB, LoopInfo &LI,
2244                                      const BoxedLoopsSetTy &BoxedLoops) {
2245   auto *L = LI.getLoopFor(BB);
2246   while (BoxedLoops.count(L))
2247     L = L->getParentLoop();
2248   return L;
2249 }
2250 
2251 /// Adjust the dimensions of @p Dom that was constructed for @p OldL
2252 ///        to be compatible to domains constructed for loop @p NewL.
2253 ///
2254 /// This function assumes @p NewL and @p OldL are equal or there is a CFG
2255 /// edge from @p OldL to @p NewL.
2256 static __isl_give isl_set *adjustDomainDimensions(Scop &S,
2257                                                   __isl_take isl_set *Dom,
2258                                                   Loop *OldL, Loop *NewL) {
2259 
2260   // If the loops are the same there is nothing to do.
2261   if (NewL == OldL)
2262     return Dom;
2263 
2264   int OldDepth = S.getRelativeLoopDepth(OldL);
2265   int NewDepth = S.getRelativeLoopDepth(NewL);
2266   // If both loops are non-affine loops there is nothing to do.
2267   if (OldDepth == -1 && NewDepth == -1)
2268     return Dom;
2269 
2270   // Distinguish three cases:
2271   //   1) The depth is the same but the loops are not.
2272   //      => One loop was left one was entered.
2273   //   2) The depth increased from OldL to NewL.
2274   //      => One loop was entered, none was left.
2275   //   3) The depth decreased from OldL to NewL.
2276   //      => Loops were left were difference of the depths defines how many.
2277   if (OldDepth == NewDepth) {
2278     assert(OldL->getParentLoop() == NewL->getParentLoop());
2279     Dom = isl_set_project_out(Dom, isl_dim_set, NewDepth, 1);
2280     Dom = isl_set_add_dims(Dom, isl_dim_set, 1);
2281     Dom = addDomainDimId(Dom, NewDepth, NewL);
2282   } else if (OldDepth < NewDepth) {
2283     assert(OldDepth + 1 == NewDepth);
2284     auto &R = S.getRegion();
2285     (void)R;
2286     assert(NewL->getParentLoop() == OldL ||
2287            ((!OldL || !R.contains(OldL)) && R.contains(NewL)));
2288     Dom = isl_set_add_dims(Dom, isl_dim_set, 1);
2289     Dom = addDomainDimId(Dom, NewDepth, NewL);
2290   } else {
2291     assert(OldDepth > NewDepth);
2292     int Diff = OldDepth - NewDepth;
2293     int NumDim = isl_set_n_dim(Dom);
2294     assert(NumDim >= Diff);
2295     Dom = isl_set_project_out(Dom, isl_dim_set, NumDim - Diff, Diff);
2296   }
2297 
2298   return Dom;
2299 }
2300 
2301 bool Scop::propagateInvalidStmtDomains(Region *R, DominatorTree &DT,
2302                                        LoopInfo &LI) {
2303   auto &BoxedLoops = getBoxedLoops();
2304 
2305   ReversePostOrderTraversal<Region *> RTraversal(R);
2306   for (auto *RN : RTraversal) {
2307 
2308     // Recurse for affine subregions but go on for basic blocks and non-affine
2309     // subregions.
2310     if (RN->isSubRegion()) {
2311       Region *SubRegion = RN->getNodeAs<Region>();
2312       if (!isNonAffineSubRegion(SubRegion)) {
2313         propagateInvalidStmtDomains(SubRegion, DT, LI);
2314         continue;
2315       }
2316     }
2317 
2318     bool ContainsErrorBlock = containsErrorBlock(RN, getRegion(), LI, DT);
2319     BasicBlock *BB = getRegionNodeBasicBlock(RN);
2320     ScopStmt *Stmt = getStmtFor(BB);
2321     isl_set *&Domain = DomainMap[BB];
2322     assert(Domain && "Cannot propagate a nullptr");
2323 
2324     auto *InvalidDomain = Stmt->getInvalidDomain();
2325     bool IsInvalidBlock =
2326         ContainsErrorBlock || isl_set_is_subset(Domain, InvalidDomain);
2327 
2328     if (!IsInvalidBlock) {
2329       InvalidDomain = isl_set_intersect(InvalidDomain, isl_set_copy(Domain));
2330     } else {
2331       isl_set_free(InvalidDomain);
2332       InvalidDomain = Domain;
2333       isl_set *DomPar = isl_set_params(isl_set_copy(Domain));
2334       recordAssumption(ERRORBLOCK, DomPar, BB->getTerminator()->getDebugLoc(),
2335                        AS_RESTRICTION);
2336       Domain = nullptr;
2337     }
2338 
2339     if (isl_set_is_empty(InvalidDomain)) {
2340       Stmt->setInvalidDomain(InvalidDomain);
2341       continue;
2342     }
2343 
2344     auto *BBLoop = getRegionNodeLoop(RN, LI);
2345     auto *TI = BB->getTerminator();
2346     unsigned NumSuccs = RN->isSubRegion() ? 1 : TI->getNumSuccessors();
2347     for (unsigned u = 0; u < NumSuccs; u++) {
2348       auto *SuccBB = getRegionNodeSuccessor(RN, TI, u);
2349       auto *SuccStmt = getStmtFor(SuccBB);
2350 
2351       // Skip successors outside the SCoP.
2352       if (!SuccStmt)
2353         continue;
2354 
2355       // Skip backedges.
2356       if (DT.dominates(SuccBB, BB))
2357         continue;
2358 
2359       auto *SuccBBLoop = getFirstNonBoxedLoopFor(SuccBB, LI, BoxedLoops);
2360       auto *AdjustedInvalidDomain = adjustDomainDimensions(
2361           *this, isl_set_copy(InvalidDomain), BBLoop, SuccBBLoop);
2362       auto *SuccInvalidDomain = SuccStmt->getInvalidDomain();
2363       SuccInvalidDomain =
2364           isl_set_union(SuccInvalidDomain, AdjustedInvalidDomain);
2365       SuccInvalidDomain = isl_set_coalesce(SuccInvalidDomain);
2366       unsigned NumConjucts = isl_set_n_basic_set(SuccInvalidDomain);
2367       SuccStmt->setInvalidDomain(SuccInvalidDomain);
2368 
2369       // Check if the maximal number of domain disjunctions was reached.
2370       // In case this happens we will bail.
2371       if (NumConjucts < MaxDisjunctionsInDomain)
2372         continue;
2373 
2374       isl_set_free(InvalidDomain);
2375       invalidate(COMPLEXITY, TI->getDebugLoc());
2376       return false;
2377     }
2378 
2379     Stmt->setInvalidDomain(InvalidDomain);
2380   }
2381 
2382   return true;
2383 }
2384 
2385 void Scop::propagateDomainConstraintsToRegionExit(
2386     BasicBlock *BB, Loop *BBLoop,
2387     SmallPtrSetImpl<BasicBlock *> &FinishedExitBlocks, LoopInfo &LI) {
2388 
2389   // Check if the block @p BB is the entry of a region. If so we propagate it's
2390   // domain to the exit block of the region. Otherwise we are done.
2391   auto *RI = R.getRegionInfo();
2392   auto *BBReg = RI ? RI->getRegionFor(BB) : nullptr;
2393   auto *ExitBB = BBReg ? BBReg->getExit() : nullptr;
2394   if (!BBReg || BBReg->getEntry() != BB || !contains(ExitBB))
2395     return;
2396 
2397   auto &BoxedLoops = getBoxedLoops();
2398   // Do not propagate the domain if there is a loop backedge inside the region
2399   // that would prevent the exit block from beeing executed.
2400   auto *L = BBLoop;
2401   while (L && contains(L)) {
2402     SmallVector<BasicBlock *, 4> LatchBBs;
2403     BBLoop->getLoopLatches(LatchBBs);
2404     for (auto *LatchBB : LatchBBs)
2405       if (BB != LatchBB && BBReg->contains(LatchBB))
2406         return;
2407     L = L->getParentLoop();
2408   }
2409 
2410   auto *Domain = DomainMap[BB];
2411   assert(Domain && "Cannot propagate a nullptr");
2412 
2413   auto *ExitBBLoop = getFirstNonBoxedLoopFor(ExitBB, LI, BoxedLoops);
2414 
2415   // Since the dimensions of @p BB and @p ExitBB might be different we have to
2416   // adjust the domain before we can propagate it.
2417   auto *AdjustedDomain =
2418       adjustDomainDimensions(*this, isl_set_copy(Domain), BBLoop, ExitBBLoop);
2419   auto *&ExitDomain = DomainMap[ExitBB];
2420 
2421   // If the exit domain is not yet created we set it otherwise we "add" the
2422   // current domain.
2423   ExitDomain =
2424       ExitDomain ? isl_set_union(AdjustedDomain, ExitDomain) : AdjustedDomain;
2425 
2426   // Initialize the invalid domain.
2427   auto *ExitStmt = getStmtFor(ExitBB);
2428   ExitStmt->setInvalidDomain(isl_set_empty(isl_set_get_space(ExitDomain)));
2429 
2430   FinishedExitBlocks.insert(ExitBB);
2431 }
2432 
2433 bool Scop::buildDomainsWithBranchConstraints(Region *R, DominatorTree &DT,
2434                                              LoopInfo &LI) {
2435   // To create the domain for each block in R we iterate over all blocks and
2436   // subregions in R and propagate the conditions under which the current region
2437   // element is executed. To this end we iterate in reverse post order over R as
2438   // it ensures that we first visit all predecessors of a region node (either a
2439   // basic block or a subregion) before we visit the region node itself.
2440   // Initially, only the domain for the SCoP region entry block is set and from
2441   // there we propagate the current domain to all successors, however we add the
2442   // condition that the successor is actually executed next.
2443   // As we are only interested in non-loop carried constraints here we can
2444   // simply skip loop back edges.
2445 
2446   SmallPtrSet<BasicBlock *, 8> FinishedExitBlocks;
2447   ReversePostOrderTraversal<Region *> RTraversal(R);
2448   for (auto *RN : RTraversal) {
2449 
2450     // Recurse for affine subregions but go on for basic blocks and non-affine
2451     // subregions.
2452     if (RN->isSubRegion()) {
2453       Region *SubRegion = RN->getNodeAs<Region>();
2454       if (!isNonAffineSubRegion(SubRegion)) {
2455         if (!buildDomainsWithBranchConstraints(SubRegion, DT, LI))
2456           return false;
2457         continue;
2458       }
2459     }
2460 
2461     if (containsErrorBlock(RN, getRegion(), LI, DT))
2462       HasErrorBlock = true;
2463 
2464     BasicBlock *BB = getRegionNodeBasicBlock(RN);
2465     TerminatorInst *TI = BB->getTerminator();
2466 
2467     if (isa<UnreachableInst>(TI))
2468       continue;
2469 
2470     isl_set *Domain = DomainMap.lookup(BB);
2471     if (!Domain)
2472       continue;
2473     MaxLoopDepth = std::max(MaxLoopDepth, isl_set_n_dim(Domain));
2474 
2475     auto *BBLoop = getRegionNodeLoop(RN, LI);
2476     // Propagate the domain from BB directly to blocks that have a superset
2477     // domain, at the moment only region exit nodes of regions that start in BB.
2478     propagateDomainConstraintsToRegionExit(BB, BBLoop, FinishedExitBlocks, LI);
2479 
2480     // If all successors of BB have been set a domain through the propagation
2481     // above we do not need to build condition sets but can just skip this
2482     // block. However, it is important to note that this is a local property
2483     // with regards to the region @p R. To this end FinishedExitBlocks is a
2484     // local variable.
2485     auto IsFinishedRegionExit = [&FinishedExitBlocks](BasicBlock *SuccBB) {
2486       return FinishedExitBlocks.count(SuccBB);
2487     };
2488     if (std::all_of(succ_begin(BB), succ_end(BB), IsFinishedRegionExit))
2489       continue;
2490 
2491     // Build the condition sets for the successor nodes of the current region
2492     // node. If it is a non-affine subregion we will always execute the single
2493     // exit node, hence the single entry node domain is the condition set. For
2494     // basic blocks we use the helper function buildConditionSets.
2495     SmallVector<isl_set *, 8> ConditionSets;
2496     if (RN->isSubRegion())
2497       ConditionSets.push_back(isl_set_copy(Domain));
2498     else if (!buildConditionSets(*getStmtFor(BB), TI, BBLoop, Domain,
2499                                  ConditionSets))
2500       return false;
2501 
2502     // Now iterate over the successors and set their initial domain based on
2503     // their condition set. We skip back edges here and have to be careful when
2504     // we leave a loop not to keep constraints over a dimension that doesn't
2505     // exist anymore.
2506     assert(RN->isSubRegion() || TI->getNumSuccessors() == ConditionSets.size());
2507     for (unsigned u = 0, e = ConditionSets.size(); u < e; u++) {
2508       isl_set *CondSet = ConditionSets[u];
2509       BasicBlock *SuccBB = getRegionNodeSuccessor(RN, TI, u);
2510 
2511       auto *SuccStmt = getStmtFor(SuccBB);
2512       // Skip blocks outside the region.
2513       if (!SuccStmt) {
2514         isl_set_free(CondSet);
2515         continue;
2516       }
2517 
2518       // If we propagate the domain of some block to "SuccBB" we do not have to
2519       // adjust the domain.
2520       if (FinishedExitBlocks.count(SuccBB)) {
2521         isl_set_free(CondSet);
2522         continue;
2523       }
2524 
2525       // Skip back edges.
2526       if (DT.dominates(SuccBB, BB)) {
2527         isl_set_free(CondSet);
2528         continue;
2529       }
2530 
2531       auto &BoxedLoops = getBoxedLoops();
2532       auto *SuccBBLoop = getFirstNonBoxedLoopFor(SuccBB, LI, BoxedLoops);
2533       CondSet = adjustDomainDimensions(*this, CondSet, BBLoop, SuccBBLoop);
2534 
2535       // Set the domain for the successor or merge it with an existing domain in
2536       // case there are multiple paths (without loop back edges) to the
2537       // successor block.
2538       isl_set *&SuccDomain = DomainMap[SuccBB];
2539 
2540       if (SuccDomain) {
2541         SuccDomain = isl_set_coalesce(isl_set_union(SuccDomain, CondSet));
2542       } else {
2543         // Initialize the invalid domain.
2544         SuccStmt->setInvalidDomain(isl_set_empty(isl_set_get_space(CondSet)));
2545         SuccDomain = CondSet;
2546       }
2547 
2548       // Check if the maximal number of domain disjunctions was reached.
2549       // In case this happens we will clean up and bail.
2550       if (isl_set_n_basic_set(SuccDomain) < MaxDisjunctionsInDomain)
2551         continue;
2552 
2553       invalidate(COMPLEXITY, DebugLoc());
2554       while (++u < ConditionSets.size())
2555         isl_set_free(ConditionSets[u]);
2556       return false;
2557     }
2558   }
2559 
2560   return true;
2561 }
2562 
2563 __isl_give isl_set *
2564 Scop::getPredecessorDomainConstraints(BasicBlock *BB,
2565                                       __isl_keep isl_set *Domain,
2566                                       DominatorTree &DT, LoopInfo &LI) {
2567   // If @p BB is the ScopEntry we are done
2568   if (R.getEntry() == BB)
2569     return isl_set_universe(isl_set_get_space(Domain));
2570 
2571   // The set of boxed loops (loops in non-affine subregions) for this SCoP.
2572   auto &BoxedLoops = getBoxedLoops();
2573 
2574   // The region info of this function.
2575   auto &RI = *R.getRegionInfo();
2576 
2577   auto *BBLoop = getFirstNonBoxedLoopFor(BB, LI, BoxedLoops);
2578 
2579   // A domain to collect all predecessor domains, thus all conditions under
2580   // which the block is executed. To this end we start with the empty domain.
2581   isl_set *PredDom = isl_set_empty(isl_set_get_space(Domain));
2582 
2583   // Set of regions of which the entry block domain has been propagated to BB.
2584   // all predecessors inside any of the regions can be skipped.
2585   SmallSet<Region *, 8> PropagatedRegions;
2586 
2587   for (auto *PredBB : predecessors(BB)) {
2588     // Skip backedges.
2589     if (DT.dominates(BB, PredBB))
2590       continue;
2591 
2592     // If the predecessor is in a region we used for propagation we can skip it.
2593     auto PredBBInRegion = [PredBB](Region *PR) { return PR->contains(PredBB); };
2594     if (std::any_of(PropagatedRegions.begin(), PropagatedRegions.end(),
2595                     PredBBInRegion)) {
2596       continue;
2597     }
2598 
2599     // Check if there is a valid region we can use for propagation, thus look
2600     // for a region that contains the predecessor and has @p BB as exit block.
2601     auto *PredR = RI.getRegionFor(PredBB);
2602     while (PredR->getExit() != BB && !PredR->contains(BB))
2603       PredR->getParent();
2604 
2605     // If a valid region for propagation was found use the entry of that region
2606     // for propagation, otherwise the PredBB directly.
2607     if (PredR->getExit() == BB) {
2608       PredBB = PredR->getEntry();
2609       PropagatedRegions.insert(PredR);
2610     }
2611 
2612     auto *PredBBDom = getDomainConditions(PredBB);
2613     auto *PredBBLoop = getFirstNonBoxedLoopFor(PredBB, LI, BoxedLoops);
2614     PredBBDom = adjustDomainDimensions(*this, PredBBDom, PredBBLoop, BBLoop);
2615 
2616     PredDom = isl_set_union(PredDom, PredBBDom);
2617   }
2618 
2619   return PredDom;
2620 }
2621 
2622 bool Scop::propagateDomainConstraints(Region *R, DominatorTree &DT,
2623                                       LoopInfo &LI) {
2624   // Iterate over the region R and propagate the domain constrains from the
2625   // predecessors to the current node. In contrast to the
2626   // buildDomainsWithBranchConstraints function, this one will pull the domain
2627   // information from the predecessors instead of pushing it to the successors.
2628   // Additionally, we assume the domains to be already present in the domain
2629   // map here. However, we iterate again in reverse post order so we know all
2630   // predecessors have been visited before a block or non-affine subregion is
2631   // visited.
2632 
2633   ReversePostOrderTraversal<Region *> RTraversal(R);
2634   for (auto *RN : RTraversal) {
2635 
2636     // Recurse for affine subregions but go on for basic blocks and non-affine
2637     // subregions.
2638     if (RN->isSubRegion()) {
2639       Region *SubRegion = RN->getNodeAs<Region>();
2640       if (!isNonAffineSubRegion(SubRegion)) {
2641         if (!propagateDomainConstraints(SubRegion, DT, LI))
2642           return false;
2643         continue;
2644       }
2645     }
2646 
2647     BasicBlock *BB = getRegionNodeBasicBlock(RN);
2648     isl_set *&Domain = DomainMap[BB];
2649     assert(Domain);
2650 
2651     // Under the union of all predecessor conditions we can reach this block.
2652     auto *PredDom = getPredecessorDomainConstraints(BB, Domain, DT, LI);
2653     Domain = isl_set_coalesce(isl_set_intersect(Domain, PredDom));
2654     Domain = isl_set_align_params(Domain, getParamSpace());
2655 
2656     Loop *BBLoop = getRegionNodeLoop(RN, LI);
2657     if (BBLoop && BBLoop->getHeader() == BB && contains(BBLoop))
2658       if (!addLoopBoundsToHeaderDomain(BBLoop, LI))
2659         return false;
2660   }
2661 
2662   return true;
2663 }
2664 
2665 /// Create a map to map from a given iteration to a subsequent iteration.
2666 ///
2667 /// This map maps from SetSpace -> SetSpace where the dimensions @p Dim
2668 /// is incremented by one and all other dimensions are equal, e.g.,
2669 ///             [i0, i1, i2, i3] -> [i0, i1, i2 + 1, i3]
2670 ///
2671 /// if @p Dim is 2 and @p SetSpace has 4 dimensions.
2672 static __isl_give isl_map *
2673 createNextIterationMap(__isl_take isl_space *SetSpace, unsigned Dim) {
2674   auto *MapSpace = isl_space_map_from_set(SetSpace);
2675   auto *NextIterationMap = isl_map_universe(isl_space_copy(MapSpace));
2676   for (unsigned u = 0; u < isl_map_n_in(NextIterationMap); u++)
2677     if (u != Dim)
2678       NextIterationMap =
2679           isl_map_equate(NextIterationMap, isl_dim_in, u, isl_dim_out, u);
2680   auto *C = isl_constraint_alloc_equality(isl_local_space_from_space(MapSpace));
2681   C = isl_constraint_set_constant_si(C, 1);
2682   C = isl_constraint_set_coefficient_si(C, isl_dim_in, Dim, 1);
2683   C = isl_constraint_set_coefficient_si(C, isl_dim_out, Dim, -1);
2684   NextIterationMap = isl_map_add_constraint(NextIterationMap, C);
2685   return NextIterationMap;
2686 }
2687 
2688 bool Scop::addLoopBoundsToHeaderDomain(Loop *L, LoopInfo &LI) {
2689   int LoopDepth = getRelativeLoopDepth(L);
2690   assert(LoopDepth >= 0 && "Loop in region should have at least depth one");
2691 
2692   BasicBlock *HeaderBB = L->getHeader();
2693   assert(DomainMap.count(HeaderBB));
2694   isl_set *&HeaderBBDom = DomainMap[HeaderBB];
2695 
2696   isl_map *NextIterationMap =
2697       createNextIterationMap(isl_set_get_space(HeaderBBDom), LoopDepth);
2698 
2699   isl_set *UnionBackedgeCondition =
2700       isl_set_empty(isl_set_get_space(HeaderBBDom));
2701 
2702   SmallVector<llvm::BasicBlock *, 4> LatchBlocks;
2703   L->getLoopLatches(LatchBlocks);
2704 
2705   for (BasicBlock *LatchBB : LatchBlocks) {
2706 
2707     // If the latch is only reachable via error statements we skip it.
2708     isl_set *LatchBBDom = DomainMap.lookup(LatchBB);
2709     if (!LatchBBDom)
2710       continue;
2711 
2712     isl_set *BackedgeCondition = nullptr;
2713 
2714     TerminatorInst *TI = LatchBB->getTerminator();
2715     BranchInst *BI = dyn_cast<BranchInst>(TI);
2716     if (BI && BI->isUnconditional())
2717       BackedgeCondition = isl_set_copy(LatchBBDom);
2718     else {
2719       SmallVector<isl_set *, 8> ConditionSets;
2720       int idx = BI->getSuccessor(0) != HeaderBB;
2721       if (!buildConditionSets(*getStmtFor(LatchBB), TI, L, LatchBBDom,
2722                               ConditionSets))
2723         return false;
2724 
2725       // Free the non back edge condition set as we do not need it.
2726       isl_set_free(ConditionSets[1 - idx]);
2727 
2728       BackedgeCondition = ConditionSets[idx];
2729     }
2730 
2731     int LatchLoopDepth = getRelativeLoopDepth(LI.getLoopFor(LatchBB));
2732     assert(LatchLoopDepth >= LoopDepth);
2733     BackedgeCondition =
2734         isl_set_project_out(BackedgeCondition, isl_dim_set, LoopDepth + 1,
2735                             LatchLoopDepth - LoopDepth);
2736     UnionBackedgeCondition =
2737         isl_set_union(UnionBackedgeCondition, BackedgeCondition);
2738   }
2739 
2740   isl_map *ForwardMap = isl_map_lex_le(isl_set_get_space(HeaderBBDom));
2741   for (int i = 0; i < LoopDepth; i++)
2742     ForwardMap = isl_map_equate(ForwardMap, isl_dim_in, i, isl_dim_out, i);
2743 
2744   isl_set *UnionBackedgeConditionComplement =
2745       isl_set_complement(UnionBackedgeCondition);
2746   UnionBackedgeConditionComplement = isl_set_lower_bound_si(
2747       UnionBackedgeConditionComplement, isl_dim_set, LoopDepth, 0);
2748   UnionBackedgeConditionComplement =
2749       isl_set_apply(UnionBackedgeConditionComplement, ForwardMap);
2750   HeaderBBDom = isl_set_subtract(HeaderBBDom, UnionBackedgeConditionComplement);
2751   HeaderBBDom = isl_set_apply(HeaderBBDom, NextIterationMap);
2752 
2753   auto Parts = partitionSetParts(HeaderBBDom, LoopDepth);
2754   HeaderBBDom = Parts.second;
2755 
2756   // Check if there is a <nsw> tagged AddRec for this loop and if so do not add
2757   // the bounded assumptions to the context as they are already implied by the
2758   // <nsw> tag.
2759   if (Affinator.hasNSWAddRecForLoop(L)) {
2760     isl_set_free(Parts.first);
2761     return true;
2762   }
2763 
2764   isl_set *UnboundedCtx = isl_set_params(Parts.first);
2765   recordAssumption(INFINITELOOP, UnboundedCtx,
2766                    HeaderBB->getTerminator()->getDebugLoc(), AS_RESTRICTION);
2767   return true;
2768 }
2769 
2770 MemoryAccess *Scop::lookupBasePtrAccess(MemoryAccess *MA) {
2771   auto *BaseAddr = SE->getSCEV(MA->getBaseAddr());
2772   auto *PointerBase = dyn_cast<SCEVUnknown>(SE->getPointerBase(BaseAddr));
2773   if (!PointerBase)
2774     return nullptr;
2775 
2776   auto *PointerBaseInst = dyn_cast<Instruction>(PointerBase->getValue());
2777   if (!PointerBaseInst)
2778     return nullptr;
2779 
2780   auto *BasePtrStmt = getStmtFor(PointerBaseInst);
2781   if (!BasePtrStmt)
2782     return nullptr;
2783 
2784   return BasePtrStmt->getArrayAccessOrNULLFor(PointerBaseInst);
2785 }
2786 
2787 bool Scop::hasNonHoistableBasePtrInScop(MemoryAccess *MA,
2788                                         __isl_keep isl_union_map *Writes) {
2789   if (auto *BasePtrMA = lookupBasePtrAccess(MA)) {
2790     auto *NHCtx = getNonHoistableCtx(BasePtrMA, Writes);
2791     bool Hoistable = NHCtx != nullptr;
2792     isl_set_free(NHCtx);
2793     return !Hoistable;
2794   }
2795 
2796   auto *BaseAddr = SE->getSCEV(MA->getBaseAddr());
2797   auto *PointerBase = dyn_cast<SCEVUnknown>(SE->getPointerBase(BaseAddr));
2798   if (auto *BasePtrInst = dyn_cast<Instruction>(PointerBase->getValue()))
2799     if (!isa<LoadInst>(BasePtrInst))
2800       return contains(BasePtrInst);
2801 
2802   return false;
2803 }
2804 
2805 bool Scop::buildAliasChecks(AliasAnalysis &AA) {
2806   if (!PollyUseRuntimeAliasChecks)
2807     return true;
2808 
2809   if (buildAliasGroups(AA))
2810     return true;
2811 
2812   // If a problem occurs while building the alias groups we need to delete
2813   // this SCoP and pretend it wasn't valid in the first place. To this end
2814   // we make the assumed context infeasible.
2815   invalidate(ALIASING, DebugLoc());
2816 
2817   DEBUG(dbgs() << "\n\nNOTE: Run time checks for " << getNameStr()
2818                << " could not be created as the number of parameters involved "
2819                   "is too high. The SCoP will be "
2820                   "dismissed.\nUse:\n\t--polly-rtc-max-parameters=X\nto adjust "
2821                   "the maximal number of parameters but be advised that the "
2822                   "compile time might increase exponentially.\n\n");
2823   return false;
2824 }
2825 
2826 bool Scop::buildAliasGroups(AliasAnalysis &AA) {
2827   // To create sound alias checks we perform the following steps:
2828   //   o) Use the alias analysis and an alias set tracker to build alias sets
2829   //      for all memory accesses inside the SCoP.
2830   //   o) For each alias set we then map the aliasing pointers back to the
2831   //      memory accesses we know, thus obtain groups of memory accesses which
2832   //      might alias.
2833   //   o) We divide each group based on the domains of the minimal/maximal
2834   //      accesses. That means two minimal/maximal accesses are only in a group
2835   //      if their access domains intersect, otherwise they are in different
2836   //      ones.
2837   //   o) We partition each group into read only and non read only accesses.
2838   //   o) For each group with more than one base pointer we then compute minimal
2839   //      and maximal accesses to each array of a group in read only and non
2840   //      read only partitions separately.
2841   using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
2842 
2843   AliasSetTracker AST(AA);
2844 
2845   DenseMap<Value *, MemoryAccess *> PtrToAcc;
2846   DenseSet<Value *> HasWriteAccess;
2847   for (ScopStmt &Stmt : *this) {
2848 
2849     // Skip statements with an empty domain as they will never be executed.
2850     isl_set *StmtDomain = Stmt.getDomain();
2851     bool StmtDomainEmpty = isl_set_is_empty(StmtDomain);
2852     isl_set_free(StmtDomain);
2853     if (StmtDomainEmpty)
2854       continue;
2855 
2856     for (MemoryAccess *MA : Stmt) {
2857       if (MA->isScalarKind())
2858         continue;
2859       if (!MA->isRead())
2860         HasWriteAccess.insert(MA->getBaseAddr());
2861       MemAccInst Acc(MA->getAccessInstruction());
2862       if (MA->isRead() && isa<MemTransferInst>(Acc))
2863         PtrToAcc[cast<MemTransferInst>(Acc)->getSource()] = MA;
2864       else
2865         PtrToAcc[Acc.getPointerOperand()] = MA;
2866       AST.add(Acc);
2867     }
2868   }
2869 
2870   SmallVector<AliasGroupTy, 4> AliasGroups;
2871   for (AliasSet &AS : AST) {
2872     if (AS.isMustAlias() || AS.isForwardingAliasSet())
2873       continue;
2874     AliasGroupTy AG;
2875     for (auto &PR : AS)
2876       AG.push_back(PtrToAcc[PR.getValue()]);
2877     if (AG.size() < 2)
2878       continue;
2879     AliasGroups.push_back(std::move(AG));
2880   }
2881 
2882   // Split the alias groups based on their domain.
2883   for (unsigned u = 0; u < AliasGroups.size(); u++) {
2884     AliasGroupTy NewAG;
2885     AliasGroupTy &AG = AliasGroups[u];
2886     AliasGroupTy::iterator AGI = AG.begin();
2887     isl_set *AGDomain = getAccessDomain(*AGI);
2888     while (AGI != AG.end()) {
2889       MemoryAccess *MA = *AGI;
2890       isl_set *MADomain = getAccessDomain(MA);
2891       if (isl_set_is_disjoint(AGDomain, MADomain)) {
2892         NewAG.push_back(MA);
2893         AGI = AG.erase(AGI);
2894         isl_set_free(MADomain);
2895       } else {
2896         AGDomain = isl_set_union(AGDomain, MADomain);
2897         AGI++;
2898       }
2899     }
2900     if (NewAG.size() > 1)
2901       AliasGroups.push_back(std::move(NewAG));
2902     isl_set_free(AGDomain);
2903   }
2904 
2905   auto &F = getFunction();
2906   MapVector<const Value *, SmallPtrSet<MemoryAccess *, 8>> ReadOnlyPairs;
2907   SmallPtrSet<const Value *, 4> NonReadOnlyBaseValues;
2908   for (AliasGroupTy &AG : AliasGroups) {
2909     NonReadOnlyBaseValues.clear();
2910     ReadOnlyPairs.clear();
2911 
2912     if (AG.size() < 2) {
2913       AG.clear();
2914       continue;
2915     }
2916 
2917     for (auto II = AG.begin(); II != AG.end();) {
2918       emitOptimizationRemarkAnalysis(
2919           F.getContext(), DEBUG_TYPE, F,
2920           (*II)->getAccessInstruction()->getDebugLoc(),
2921           "Possibly aliasing pointer, use restrict keyword.");
2922 
2923       Value *BaseAddr = (*II)->getBaseAddr();
2924       if (HasWriteAccess.count(BaseAddr)) {
2925         NonReadOnlyBaseValues.insert(BaseAddr);
2926         II++;
2927       } else {
2928         ReadOnlyPairs[BaseAddr].insert(*II);
2929         II = AG.erase(II);
2930       }
2931     }
2932 
2933     // If we don't have read only pointers check if there are at least two
2934     // non read only pointers, otherwise clear the alias group.
2935     if (ReadOnlyPairs.empty() && NonReadOnlyBaseValues.size() <= 1) {
2936       AG.clear();
2937       continue;
2938     }
2939 
2940     // If we don't have non read only pointers clear the alias group.
2941     if (NonReadOnlyBaseValues.empty()) {
2942       AG.clear();
2943       continue;
2944     }
2945 
2946     // Check if we have non-affine accesses left, if so bail out as we cannot
2947     // generate a good access range yet.
2948     for (auto *MA : AG) {
2949       if (!MA->isAffine()) {
2950         invalidate(ALIASING, MA->getAccessInstruction()->getDebugLoc());
2951         return false;
2952       }
2953       if (auto *BasePtrMA = lookupBasePtrAccess(MA))
2954         addRequiredInvariantLoad(
2955             cast<LoadInst>(BasePtrMA->getAccessInstruction()));
2956     }
2957     for (auto &ReadOnlyPair : ReadOnlyPairs)
2958       for (auto *MA : ReadOnlyPair.second) {
2959         if (!MA->isAffine()) {
2960           invalidate(ALIASING, MA->getAccessInstruction()->getDebugLoc());
2961           return false;
2962         }
2963         if (auto *BasePtrMA = lookupBasePtrAccess(MA))
2964           addRequiredInvariantLoad(
2965               cast<LoadInst>(BasePtrMA->getAccessInstruction()));
2966       }
2967 
2968     // Calculate minimal and maximal accesses for non read only accesses.
2969     MinMaxAliasGroups.emplace_back();
2970     MinMaxVectorPairTy &pair = MinMaxAliasGroups.back();
2971     MinMaxVectorTy &MinMaxAccessesNonReadOnly = pair.first;
2972     MinMaxVectorTy &MinMaxAccessesReadOnly = pair.second;
2973     MinMaxAccessesNonReadOnly.reserve(AG.size());
2974 
2975     isl_union_map *Accesses = isl_union_map_empty(getParamSpace());
2976 
2977     // AG contains only non read only accesses.
2978     for (MemoryAccess *MA : AG)
2979       Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation());
2980 
2981     bool Valid = calculateMinMaxAccess(Accesses, getDomains(),
2982                                        MinMaxAccessesNonReadOnly);
2983 
2984     // Bail out if the number of values we need to compare is too large.
2985     // This is important as the number of comparisions grows quadratically with
2986     // the number of values we need to compare.
2987     if (!Valid || (MinMaxAccessesNonReadOnly.size() + ReadOnlyPairs.size() >
2988                    RunTimeChecksMaxArraysPerGroup))
2989       return false;
2990 
2991     // Calculate minimal and maximal accesses for read only accesses.
2992     MinMaxAccessesReadOnly.reserve(ReadOnlyPairs.size());
2993     Accesses = isl_union_map_empty(getParamSpace());
2994 
2995     for (const auto &ReadOnlyPair : ReadOnlyPairs)
2996       for (MemoryAccess *MA : ReadOnlyPair.second)
2997         Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation());
2998 
2999     Valid =
3000         calculateMinMaxAccess(Accesses, getDomains(), MinMaxAccessesReadOnly);
3001 
3002     if (!Valid)
3003       return false;
3004   }
3005 
3006   return true;
3007 }
3008 
3009 /// Get the smallest loop that contains @p S but is not in @p S.
3010 static Loop *getLoopSurroundingScop(Scop &S, LoopInfo &LI) {
3011   // Start with the smallest loop containing the entry and expand that
3012   // loop until it contains all blocks in the region. If there is a loop
3013   // containing all blocks in the region check if it is itself contained
3014   // and if so take the parent loop as it will be the smallest containing
3015   // the region but not contained by it.
3016   Loop *L = LI.getLoopFor(S.getEntry());
3017   while (L) {
3018     bool AllContained = true;
3019     for (auto *BB : S.blocks())
3020       AllContained &= L->contains(BB);
3021     if (AllContained)
3022       break;
3023     L = L->getParentLoop();
3024   }
3025 
3026   return L ? (S.contains(L) ? L->getParentLoop() : L) : nullptr;
3027 }
3028 
3029 Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
3030            ScopDetection::DetectionContext &DC)
3031     : SE(&ScalarEvolution), R(R), IsOptimized(false),
3032       HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false),
3033       MaxLoopDepth(0), DC(DC), IslCtx(isl_ctx_alloc(), isl_ctx_free),
3034       Context(nullptr), Affinator(this, LI), AssumedContext(nullptr),
3035       InvalidContext(nullptr), Schedule(nullptr) {
3036   if (IslOnErrorAbort)
3037     isl_options_set_on_error(getIslCtx(), ISL_ON_ERROR_ABORT);
3038   buildContext();
3039 }
3040 
3041 void Scop::init(AliasAnalysis &AA, AssumptionCache &AC, DominatorTree &DT,
3042                 LoopInfo &LI) {
3043   buildInvariantEquivalenceClasses();
3044 
3045   if (!buildDomains(&R, DT, LI))
3046     return;
3047 
3048   addUserAssumptions(AC, DT, LI);
3049 
3050   // Remove empty statements.
3051   // Exit early in case there are no executable statements left in this scop.
3052   simplifySCoP(false);
3053   if (Stmts.empty())
3054     return;
3055 
3056   // The ScopStmts now have enough information to initialize themselves.
3057   for (ScopStmt &Stmt : Stmts)
3058     Stmt.init(LI);
3059 
3060   // Check early for profitability. Afterwards it cannot change anymore,
3061   // only the runtime context could become infeasible.
3062   if (!isProfitable()) {
3063     invalidate(PROFITABLE, DebugLoc());
3064     return;
3065   }
3066 
3067   buildSchedule(LI);
3068 
3069   updateAccessDimensionality();
3070   realignParams();
3071   addUserContext();
3072 
3073   // After the context was fully constructed, thus all our knowledge about
3074   // the parameters is in there, we add all recorded assumptions to the
3075   // assumed/invalid context.
3076   addRecordedAssumptions();
3077 
3078   simplifyContexts();
3079   if (!buildAliasChecks(AA))
3080     return;
3081 
3082   hoistInvariantLoads();
3083   verifyInvariantLoads();
3084   simplifySCoP(true);
3085 
3086   // Check late for a feasible runtime context because profitability did not
3087   // change.
3088   if (!hasFeasibleRuntimeContext()) {
3089     invalidate(PROFITABLE, DebugLoc());
3090     return;
3091   }
3092 }
3093 
3094 Scop::~Scop() {
3095   isl_set_free(Context);
3096   isl_set_free(AssumedContext);
3097   isl_set_free(InvalidContext);
3098   isl_schedule_free(Schedule);
3099 
3100   for (auto &It : ParameterIds)
3101     isl_id_free(It.second);
3102 
3103   for (auto It : DomainMap)
3104     isl_set_free(It.second);
3105 
3106   for (auto &AS : RecordedAssumptions)
3107     isl_set_free(AS.Set);
3108 
3109   // Free the alias groups
3110   for (MinMaxVectorPairTy &MinMaxAccessPair : MinMaxAliasGroups) {
3111     for (MinMaxAccessTy &MMA : MinMaxAccessPair.first) {
3112       isl_pw_multi_aff_free(MMA.first);
3113       isl_pw_multi_aff_free(MMA.second);
3114     }
3115     for (MinMaxAccessTy &MMA : MinMaxAccessPair.second) {
3116       isl_pw_multi_aff_free(MMA.first);
3117       isl_pw_multi_aff_free(MMA.second);
3118     }
3119   }
3120 
3121   for (const auto &IAClass : InvariantEquivClasses)
3122     isl_set_free(IAClass.ExecutionContext);
3123 
3124   // Explicitly release all Scop objects and the underlying isl objects before
3125   // we relase the isl context.
3126   Stmts.clear();
3127   ScopArrayInfoSet.clear();
3128   ScopArrayInfoMap.clear();
3129   ScopArrayNameMap.clear();
3130   AccessFunctions.clear();
3131 }
3132 
3133 void Scop::updateAccessDimensionality() {
3134   // Check all array accesses for each base pointer and find a (virtual) element
3135   // size for the base pointer that divides all access functions.
3136   for (auto &Stmt : *this)
3137     for (auto *Access : Stmt) {
3138       if (!Access->isArrayKind())
3139         continue;
3140       auto &SAI = ScopArrayInfoMap[std::make_pair(Access->getBaseAddr(),
3141                                                   ScopArrayInfo::MK_Array)];
3142       if (SAI->getNumberOfDimensions() != 1)
3143         continue;
3144       unsigned DivisibleSize = SAI->getElemSizeInBytes();
3145       auto *Subscript = Access->getSubscript(0);
3146       while (!isDivisible(Subscript, DivisibleSize, *SE))
3147         DivisibleSize /= 2;
3148       auto *Ty = IntegerType::get(SE->getContext(), DivisibleSize * 8);
3149       SAI->updateElementType(Ty);
3150     }
3151 
3152   for (auto &Stmt : *this)
3153     for (auto &Access : Stmt)
3154       Access->updateDimensionality();
3155 }
3156 
3157 void Scop::simplifySCoP(bool AfterHoisting) {
3158   for (auto StmtIt = Stmts.begin(), StmtEnd = Stmts.end(); StmtIt != StmtEnd;) {
3159     ScopStmt &Stmt = *StmtIt;
3160 
3161     bool RemoveStmt = Stmt.isEmpty();
3162     if (!RemoveStmt)
3163       RemoveStmt = !DomainMap[Stmt.getEntryBlock()];
3164 
3165     // Remove read only statements only after invariant loop hoisting.
3166     if (!RemoveStmt && AfterHoisting) {
3167       bool OnlyRead = true;
3168       for (MemoryAccess *MA : Stmt) {
3169         if (MA->isRead())
3170           continue;
3171 
3172         OnlyRead = false;
3173         break;
3174       }
3175 
3176       RemoveStmt = OnlyRead;
3177     }
3178 
3179     if (!RemoveStmt) {
3180       StmtIt++;
3181       continue;
3182     }
3183 
3184     // Remove the statement because it is unnecessary.
3185     if (Stmt.isRegionStmt())
3186       for (BasicBlock *BB : Stmt.getRegion()->blocks())
3187         StmtMap.erase(BB);
3188     else
3189       StmtMap.erase(Stmt.getBasicBlock());
3190 
3191     StmtIt = Stmts.erase(StmtIt);
3192   }
3193 }
3194 
3195 InvariantEquivClassTy *Scop::lookupInvariantEquivClass(Value *Val) {
3196   LoadInst *LInst = dyn_cast<LoadInst>(Val);
3197   if (!LInst)
3198     return nullptr;
3199 
3200   if (Value *Rep = InvEquivClassVMap.lookup(LInst))
3201     LInst = cast<LoadInst>(Rep);
3202 
3203   Type *Ty = LInst->getType();
3204   const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
3205   for (auto &IAClass : InvariantEquivClasses) {
3206     if (PointerSCEV != IAClass.IdentifyingPointer || Ty != IAClass.AccessType)
3207       continue;
3208 
3209     auto &MAs = IAClass.InvariantAccesses;
3210     for (auto *MA : MAs)
3211       if (MA->getAccessInstruction() == Val)
3212         return &IAClass;
3213   }
3214 
3215   return nullptr;
3216 }
3217 
3218 /// Check if @p MA can always be hoisted without execution context.
3219 static bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty,
3220                                bool MAInvalidCtxIsEmpty,
3221                                bool NonHoistableCtxIsEmpty) {
3222   LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction());
3223   const DataLayout &DL = LInst->getParent()->getModule()->getDataLayout();
3224   // TODO: We can provide more information for better but more expensive
3225   //       results.
3226   if (!isDereferenceableAndAlignedPointer(LInst->getPointerOperand(),
3227                                           LInst->getAlignment(), DL))
3228     return false;
3229 
3230   // If the location might be overwritten we do not hoist it unconditionally.
3231   //
3232   // TODO: This is probably to conservative.
3233   if (!NonHoistableCtxIsEmpty)
3234     return false;
3235 
3236   // If a dereferencable load is in a statement that is modeled precisely we can
3237   // hoist it.
3238   if (StmtInvalidCtxIsEmpty && MAInvalidCtxIsEmpty)
3239     return true;
3240 
3241   // Even if the statement is not modeled precisely we can hoist the load if it
3242   // does not involve any parameters that might have been specilized by the
3243   // statement domain.
3244   for (unsigned u = 0, e = MA->getNumSubscripts(); u < e; u++)
3245     if (!isa<SCEVConstant>(MA->getSubscript(u)))
3246       return false;
3247   return true;
3248 }
3249 
3250 void Scop::addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs) {
3251 
3252   if (InvMAs.empty())
3253     return;
3254 
3255   auto *StmtInvalidCtx = Stmt.getInvalidContext();
3256   bool StmtInvalidCtxIsEmpty = isl_set_is_empty(StmtInvalidCtx);
3257 
3258   // Get the context under which the statement is executed but remove the error
3259   // context under which this statement is reached.
3260   isl_set *DomainCtx = isl_set_params(Stmt.getDomain());
3261   DomainCtx = isl_set_subtract(DomainCtx, StmtInvalidCtx);
3262 
3263   if (isl_set_n_basic_set(DomainCtx) >= MaxDisjunctionsInDomain) {
3264     auto *AccInst = InvMAs.front().MA->getAccessInstruction();
3265     invalidate(COMPLEXITY, AccInst->getDebugLoc());
3266     isl_set_free(DomainCtx);
3267     for (auto &InvMA : InvMAs)
3268       isl_set_free(InvMA.NonHoistableCtx);
3269     return;
3270   }
3271 
3272   // Project out all parameters that relate to loads in the statement. Otherwise
3273   // we could have cyclic dependences on the constraints under which the
3274   // hoisted loads are executed and we could not determine an order in which to
3275   // pre-load them. This happens because not only lower bounds are part of the
3276   // domain but also upper bounds.
3277   for (auto &InvMA : InvMAs) {
3278     auto *MA = InvMA.MA;
3279     Instruction *AccInst = MA->getAccessInstruction();
3280     if (SE->isSCEVable(AccInst->getType())) {
3281       SetVector<Value *> Values;
3282       for (const SCEV *Parameter : Parameters) {
3283         Values.clear();
3284         findValues(Parameter, *SE, Values);
3285         if (!Values.count(AccInst))
3286           continue;
3287 
3288         if (isl_id *ParamId = getIdForParam(Parameter)) {
3289           int Dim = isl_set_find_dim_by_id(DomainCtx, isl_dim_param, ParamId);
3290           DomainCtx = isl_set_eliminate(DomainCtx, isl_dim_param, Dim, 1);
3291           isl_id_free(ParamId);
3292         }
3293       }
3294     }
3295   }
3296 
3297   for (auto &InvMA : InvMAs) {
3298     auto *MA = InvMA.MA;
3299     auto *NHCtx = InvMA.NonHoistableCtx;
3300 
3301     // Check for another invariant access that accesses the same location as
3302     // MA and if found consolidate them. Otherwise create a new equivalence
3303     // class at the end of InvariantEquivClasses.
3304     LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction());
3305     Type *Ty = LInst->getType();
3306     const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
3307 
3308     auto *MAInvalidCtx = MA->getInvalidContext();
3309     bool NonHoistableCtxIsEmpty = isl_set_is_empty(NHCtx);
3310     bool MAInvalidCtxIsEmpty = isl_set_is_empty(MAInvalidCtx);
3311 
3312     isl_set *MACtx;
3313     // Check if we know that this pointer can be speculatively accessed.
3314     if (canAlwaysBeHoisted(MA, StmtInvalidCtxIsEmpty, MAInvalidCtxIsEmpty,
3315                            NonHoistableCtxIsEmpty)) {
3316       MACtx = isl_set_universe(isl_set_get_space(DomainCtx));
3317       isl_set_free(MAInvalidCtx);
3318       isl_set_free(NHCtx);
3319     } else {
3320       MACtx = isl_set_copy(DomainCtx);
3321       MACtx = isl_set_subtract(MACtx, isl_set_union(MAInvalidCtx, NHCtx));
3322       MACtx = isl_set_gist_params(MACtx, getContext());
3323     }
3324 
3325     bool Consolidated = false;
3326     for (auto &IAClass : InvariantEquivClasses) {
3327       if (PointerSCEV != IAClass.IdentifyingPointer || Ty != IAClass.AccessType)
3328         continue;
3329 
3330       // If the pointer and the type is equal check if the access function wrt.
3331       // to the domain is equal too. It can happen that the domain fixes
3332       // parameter values and these can be different for distinct part of the
3333       // SCoP. If this happens we cannot consolidate the loads but need to
3334       // create a new invariant load equivalence class.
3335       auto &MAs = IAClass.InvariantAccesses;
3336       if (!MAs.empty()) {
3337         auto *LastMA = MAs.front();
3338 
3339         auto *AR = isl_map_range(MA->getAccessRelation());
3340         auto *LastAR = isl_map_range(LastMA->getAccessRelation());
3341         bool SameAR = isl_set_is_equal(AR, LastAR);
3342         isl_set_free(AR);
3343         isl_set_free(LastAR);
3344 
3345         if (!SameAR)
3346           continue;
3347       }
3348 
3349       // Add MA to the list of accesses that are in this class.
3350       MAs.push_front(MA);
3351 
3352       Consolidated = true;
3353 
3354       // Unify the execution context of the class and this statement.
3355       isl_set *&IAClassDomainCtx = IAClass.ExecutionContext;
3356       if (IAClassDomainCtx)
3357         IAClassDomainCtx =
3358             isl_set_coalesce(isl_set_union(IAClassDomainCtx, MACtx));
3359       else
3360         IAClassDomainCtx = MACtx;
3361       break;
3362     }
3363 
3364     if (Consolidated)
3365       continue;
3366 
3367     // If we did not consolidate MA, thus did not find an equivalence class
3368     // for it, we create a new one.
3369     InvariantEquivClasses.emplace_back(
3370         InvariantEquivClassTy{PointerSCEV, MemoryAccessList{MA}, MACtx, Ty});
3371   }
3372 
3373   isl_set_free(DomainCtx);
3374 }
3375 
3376 __isl_give isl_set *Scop::getNonHoistableCtx(MemoryAccess *Access,
3377                                              __isl_keep isl_union_map *Writes) {
3378   // TODO: Loads that are not loop carried, hence are in a statement with
3379   //       zero iterators, are by construction invariant, though we
3380   //       currently "hoist" them anyway. This is necessary because we allow
3381   //       them to be treated as parameters (e.g., in conditions) and our code
3382   //       generation would otherwise use the old value.
3383 
3384   auto &Stmt = *Access->getStatement();
3385   BasicBlock *BB = Stmt.getEntryBlock();
3386 
3387   if (Access->isScalarKind() || Access->isWrite() || !Access->isAffine())
3388     return nullptr;
3389 
3390   // Skip accesses that have an invariant base pointer which is defined but
3391   // not loaded inside the SCoP. This can happened e.g., if a readnone call
3392   // returns a pointer that is used as a base address. However, as we want
3393   // to hoist indirect pointers, we allow the base pointer to be defined in
3394   // the region if it is also a memory access. Each ScopArrayInfo object
3395   // that has a base pointer origin has a base pointer that is loaded and
3396   // that it is invariant, thus it will be hoisted too. However, if there is
3397   // no base pointer origin we check that the base pointer is defined
3398   // outside the region.
3399   auto *LI = cast<LoadInst>(Access->getAccessInstruction());
3400   if (hasNonHoistableBasePtrInScop(Access, Writes))
3401     return nullptr;
3402 
3403   // Skip accesses in non-affine subregions as they might not be executed
3404   // under the same condition as the entry of the non-affine subregion.
3405   if (BB != LI->getParent())
3406     return nullptr;
3407 
3408   isl_map *AccessRelation = Access->getAccessRelation();
3409   assert(!isl_map_is_empty(AccessRelation));
3410 
3411   if (isl_map_involves_dims(AccessRelation, isl_dim_in, 0,
3412                             Stmt.getNumIterators())) {
3413     isl_map_free(AccessRelation);
3414     return nullptr;
3415   }
3416 
3417   AccessRelation = isl_map_intersect_domain(AccessRelation, Stmt.getDomain());
3418   isl_set *AccessRange = isl_map_range(AccessRelation);
3419 
3420   isl_union_map *Written = isl_union_map_intersect_range(
3421       isl_union_map_copy(Writes), isl_union_set_from_set(AccessRange));
3422   auto *WrittenCtx = isl_union_map_params(Written);
3423   bool IsWritten = !isl_set_is_empty(WrittenCtx);
3424 
3425   if (!IsWritten)
3426     return WrittenCtx;
3427 
3428   WrittenCtx = isl_set_remove_divs(WrittenCtx);
3429   bool TooComplex = isl_set_n_basic_set(WrittenCtx) >= MaxDisjunctionsInDomain;
3430   if (TooComplex || !isRequiredInvariantLoad(LI)) {
3431     isl_set_free(WrittenCtx);
3432     return nullptr;
3433   }
3434 
3435   addAssumption(INVARIANTLOAD, isl_set_copy(WrittenCtx), LI->getDebugLoc(),
3436                 AS_RESTRICTION);
3437   return WrittenCtx;
3438 }
3439 
3440 void Scop::verifyInvariantLoads() {
3441   auto &RIL = getRequiredInvariantLoads();
3442   for (LoadInst *LI : RIL) {
3443     assert(LI && contains(LI));
3444     ScopStmt *Stmt = getStmtFor(LI);
3445     if (Stmt && Stmt->getArrayAccessOrNULLFor(LI)) {
3446       invalidate(INVARIANTLOAD, LI->getDebugLoc());
3447       return;
3448     }
3449   }
3450 }
3451 
3452 void Scop::hoistInvariantLoads() {
3453   if (!PollyInvariantLoadHoisting)
3454     return;
3455 
3456   isl_union_map *Writes = getWrites();
3457   for (ScopStmt &Stmt : *this) {
3458     InvariantAccessesTy InvariantAccesses;
3459 
3460     for (MemoryAccess *Access : Stmt)
3461       if (auto *NHCtx = getNonHoistableCtx(Access, Writes))
3462         InvariantAccesses.push_back({Access, NHCtx});
3463 
3464     // Transfer the memory access from the statement to the SCoP.
3465     for (auto InvMA : InvariantAccesses)
3466       Stmt.removeMemoryAccess(InvMA.MA);
3467     addInvariantLoads(Stmt, InvariantAccesses);
3468   }
3469   isl_union_map_free(Writes);
3470 }
3471 
3472 const ScopArrayInfo *Scop::getOrCreateScopArrayInfo(
3473     Value *BasePtr, Type *ElementType, ArrayRef<const SCEV *> Sizes,
3474     ScopArrayInfo::MemoryKind Kind, const char *BaseName) {
3475   assert((BasePtr || BaseName) &&
3476          "BasePtr and BaseName can not be nullptr at the same time.");
3477   assert(!(BasePtr && BaseName) && "BaseName is redundant.");
3478   auto &SAI = BasePtr ? ScopArrayInfoMap[std::make_pair(BasePtr, Kind)]
3479                       : ScopArrayNameMap[BaseName];
3480   if (!SAI) {
3481     auto &DL = getFunction().getParent()->getDataLayout();
3482     SAI.reset(new ScopArrayInfo(BasePtr, ElementType, getIslCtx(), Sizes, Kind,
3483                                 DL, this, BaseName));
3484     ScopArrayInfoSet.insert(SAI.get());
3485   } else {
3486     SAI->updateElementType(ElementType);
3487     // In case of mismatching array sizes, we bail out by setting the run-time
3488     // context to false.
3489     if (!SAI->updateSizes(Sizes))
3490       invalidate(DELINEARIZATION, DebugLoc());
3491   }
3492   return SAI.get();
3493 }
3494 
3495 const ScopArrayInfo *
3496 Scop::createScopArrayInfo(Type *ElementType, const std::string &BaseName,
3497                           const std::vector<unsigned> &Sizes) {
3498   auto *DimSizeType = Type::getInt64Ty(getSE()->getContext());
3499   std::vector<const SCEV *> SCEVSizes;
3500 
3501   for (auto size : Sizes)
3502     SCEVSizes.push_back(getSE()->getConstant(DimSizeType, size, false));
3503 
3504   auto *SAI =
3505       getOrCreateScopArrayInfo(nullptr, ElementType, SCEVSizes,
3506                                ScopArrayInfo::MK_Array, BaseName.c_str());
3507   return SAI;
3508 }
3509 
3510 const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr,
3511                                             ScopArrayInfo::MemoryKind Kind) {
3512   auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)].get();
3513   assert(SAI && "No ScopArrayInfo available for this base pointer");
3514   return SAI;
3515 }
3516 
3517 std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
3518 
3519 std::string Scop::getAssumedContextStr() const {
3520   assert(AssumedContext && "Assumed context not yet built");
3521   return stringFromIslObj(AssumedContext);
3522 }
3523 
3524 std::string Scop::getInvalidContextStr() const {
3525   return stringFromIslObj(InvalidContext);
3526 }
3527 
3528 std::string Scop::getNameStr() const {
3529   std::string ExitName, EntryName;
3530   raw_string_ostream ExitStr(ExitName);
3531   raw_string_ostream EntryStr(EntryName);
3532 
3533   R.getEntry()->printAsOperand(EntryStr, false);
3534   EntryStr.str();
3535 
3536   if (R.getExit()) {
3537     R.getExit()->printAsOperand(ExitStr, false);
3538     ExitStr.str();
3539   } else
3540     ExitName = "FunctionExit";
3541 
3542   return EntryName + "---" + ExitName;
3543 }
3544 
3545 __isl_give isl_set *Scop::getContext() const { return isl_set_copy(Context); }
3546 __isl_give isl_space *Scop::getParamSpace() const {
3547   return isl_set_get_space(Context);
3548 }
3549 
3550 __isl_give isl_set *Scop::getAssumedContext() const {
3551   assert(AssumedContext && "Assumed context not yet built");
3552   return isl_set_copy(AssumedContext);
3553 }
3554 
3555 bool Scop::isProfitable() const {
3556   if (PollyProcessUnprofitable)
3557     return true;
3558 
3559   if (!hasFeasibleRuntimeContext())
3560     return false;
3561 
3562   if (isEmpty())
3563     return false;
3564 
3565   unsigned OptimizableStmtsOrLoops = 0;
3566   for (auto &Stmt : *this) {
3567     if (Stmt.getNumIterators() == 0)
3568       continue;
3569 
3570     bool ContainsArrayAccs = false;
3571     bool ContainsScalarAccs = false;
3572     for (auto *MA : Stmt) {
3573       if (MA->isRead())
3574         continue;
3575       ContainsArrayAccs |= MA->isArrayKind();
3576       ContainsScalarAccs |= MA->isScalarKind();
3577     }
3578 
3579     if (ContainsArrayAccs && !ContainsScalarAccs)
3580       OptimizableStmtsOrLoops += Stmt.getNumIterators();
3581   }
3582 
3583   return OptimizableStmtsOrLoops > 1;
3584 }
3585 
3586 bool Scop::hasFeasibleRuntimeContext() const {
3587   auto *PositiveContext = getAssumedContext();
3588   auto *NegativeContext = getInvalidContext();
3589   PositiveContext = addNonEmptyDomainConstraints(PositiveContext);
3590   bool IsFeasible = !(isl_set_is_empty(PositiveContext) ||
3591                       isl_set_is_subset(PositiveContext, NegativeContext));
3592   isl_set_free(PositiveContext);
3593   if (!IsFeasible) {
3594     isl_set_free(NegativeContext);
3595     return false;
3596   }
3597 
3598   auto *DomainContext = isl_union_set_params(getDomains());
3599   IsFeasible = !isl_set_is_subset(DomainContext, NegativeContext);
3600   IsFeasible &= !isl_set_is_subset(Context, NegativeContext);
3601   isl_set_free(NegativeContext);
3602   isl_set_free(DomainContext);
3603 
3604   return IsFeasible;
3605 }
3606 
3607 static std::string toString(AssumptionKind Kind) {
3608   switch (Kind) {
3609   case ALIASING:
3610     return "No-aliasing";
3611   case INBOUNDS:
3612     return "Inbounds";
3613   case WRAPPING:
3614     return "No-overflows";
3615   case UNSIGNED:
3616     return "Signed-unsigned";
3617   case COMPLEXITY:
3618     return "Low complexity";
3619   case PROFITABLE:
3620     return "Profitable";
3621   case ERRORBLOCK:
3622     return "No-error";
3623   case INFINITELOOP:
3624     return "Finite loop";
3625   case INVARIANTLOAD:
3626     return "Invariant load";
3627   case DELINEARIZATION:
3628     return "Delinearization";
3629   }
3630   llvm_unreachable("Unknown AssumptionKind!");
3631 }
3632 
3633 bool Scop::isEffectiveAssumption(__isl_keep isl_set *Set, AssumptionSign Sign) {
3634   if (Sign == AS_ASSUMPTION) {
3635     if (isl_set_is_subset(Context, Set))
3636       return false;
3637 
3638     if (isl_set_is_subset(AssumedContext, Set))
3639       return false;
3640   } else {
3641     if (isl_set_is_disjoint(Set, Context))
3642       return false;
3643 
3644     if (isl_set_is_subset(Set, InvalidContext))
3645       return false;
3646   }
3647   return true;
3648 }
3649 
3650 bool Scop::trackAssumption(AssumptionKind Kind, __isl_keep isl_set *Set,
3651                            DebugLoc Loc, AssumptionSign Sign) {
3652   if (PollyRemarksMinimal && !isEffectiveAssumption(Set, Sign))
3653     return false;
3654 
3655   auto &F = getFunction();
3656   auto Suffix = Sign == AS_ASSUMPTION ? " assumption:\t" : " restriction:\t";
3657   std::string Msg = toString(Kind) + Suffix + stringFromIslObj(Set);
3658   emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F, Loc, Msg);
3659   return true;
3660 }
3661 
3662 void Scop::addAssumption(AssumptionKind Kind, __isl_take isl_set *Set,
3663                          DebugLoc Loc, AssumptionSign Sign) {
3664   // Simplify the assumptions/restrictions first.
3665   Set = isl_set_gist_params(Set, getContext());
3666 
3667   if (!trackAssumption(Kind, Set, Loc, Sign)) {
3668     isl_set_free(Set);
3669     return;
3670   }
3671 
3672   if (Sign == AS_ASSUMPTION) {
3673     AssumedContext = isl_set_intersect(AssumedContext, Set);
3674     AssumedContext = isl_set_coalesce(AssumedContext);
3675   } else {
3676     InvalidContext = isl_set_union(InvalidContext, Set);
3677     InvalidContext = isl_set_coalesce(InvalidContext);
3678   }
3679 }
3680 
3681 void Scop::recordAssumption(AssumptionKind Kind, __isl_take isl_set *Set,
3682                             DebugLoc Loc, AssumptionSign Sign, BasicBlock *BB) {
3683   RecordedAssumptions.push_back({Kind, Sign, Set, Loc, BB});
3684 }
3685 
3686 void Scop::addRecordedAssumptions() {
3687   while (!RecordedAssumptions.empty()) {
3688     const Assumption &AS = RecordedAssumptions.pop_back_val();
3689 
3690     if (!AS.BB) {
3691       addAssumption(AS.Kind, AS.Set, AS.Loc, AS.Sign);
3692       continue;
3693     }
3694 
3695     // If the domain was deleted the assumptions are void.
3696     isl_set *Dom = getDomainConditions(AS.BB);
3697     if (!Dom) {
3698       isl_set_free(AS.Set);
3699       continue;
3700     }
3701 
3702     // If a basic block was given use its domain to simplify the assumption.
3703     // In case of restrictions we know they only have to hold on the domain,
3704     // thus we can intersect them with the domain of the block. However, for
3705     // assumptions the domain has to imply them, thus:
3706     //                     _              _____
3707     //   Dom => S   <==>   A v B   <==>   A - B
3708     //
3709     // To avoid the complement we will register A - B as a restricton not an
3710     // assumption.
3711     isl_set *S = AS.Set;
3712     if (AS.Sign == AS_RESTRICTION)
3713       S = isl_set_params(isl_set_intersect(S, Dom));
3714     else /* (AS.Sign == AS_ASSUMPTION) */
3715       S = isl_set_params(isl_set_subtract(Dom, S));
3716 
3717     addAssumption(AS.Kind, S, AS.Loc, AS_RESTRICTION);
3718   }
3719 }
3720 
3721 void Scop::invalidate(AssumptionKind Kind, DebugLoc Loc) {
3722   addAssumption(Kind, isl_set_empty(getParamSpace()), Loc, AS_ASSUMPTION);
3723 }
3724 
3725 __isl_give isl_set *Scop::getInvalidContext() const {
3726   return isl_set_copy(InvalidContext);
3727 }
3728 
3729 void Scop::printContext(raw_ostream &OS) const {
3730   OS << "Context:\n";
3731   OS.indent(4) << Context << "\n";
3732 
3733   OS.indent(4) << "Assumed Context:\n";
3734   OS.indent(4) << AssumedContext << "\n";
3735 
3736   OS.indent(4) << "Invalid Context:\n";
3737   OS.indent(4) << InvalidContext << "\n";
3738 
3739   unsigned Dim = 0;
3740   for (const SCEV *Parameter : Parameters)
3741     OS.indent(4) << "p" << Dim++ << ": " << *Parameter << "\n";
3742 }
3743 
3744 void Scop::printAliasAssumptions(raw_ostream &OS) const {
3745   int noOfGroups = 0;
3746   for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
3747     if (Pair.second.size() == 0)
3748       noOfGroups += 1;
3749     else
3750       noOfGroups += Pair.second.size();
3751   }
3752 
3753   OS.indent(4) << "Alias Groups (" << noOfGroups << "):\n";
3754   if (MinMaxAliasGroups.empty()) {
3755     OS.indent(8) << "n/a\n";
3756     return;
3757   }
3758 
3759   for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
3760 
3761     // If the group has no read only accesses print the write accesses.
3762     if (Pair.second.empty()) {
3763       OS.indent(8) << "[[";
3764       for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
3765         OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
3766            << ">";
3767       }
3768       OS << " ]]\n";
3769     }
3770 
3771     for (const MinMaxAccessTy &MMAReadOnly : Pair.second) {
3772       OS.indent(8) << "[[";
3773       OS << " <" << MMAReadOnly.first << ", " << MMAReadOnly.second << ">";
3774       for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
3775         OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
3776            << ">";
3777       }
3778       OS << " ]]\n";
3779     }
3780   }
3781 }
3782 
3783 void Scop::printStatements(raw_ostream &OS) const {
3784   OS << "Statements {\n";
3785 
3786   for (const ScopStmt &Stmt : *this)
3787     OS.indent(4) << Stmt;
3788 
3789   OS.indent(4) << "}\n";
3790 }
3791 
3792 void Scop::printArrayInfo(raw_ostream &OS) const {
3793   OS << "Arrays {\n";
3794 
3795   for (auto &Array : arrays())
3796     Array->print(OS);
3797 
3798   OS.indent(4) << "}\n";
3799 
3800   OS.indent(4) << "Arrays (Bounds as pw_affs) {\n";
3801 
3802   for (auto &Array : arrays())
3803     Array->print(OS, /* SizeAsPwAff */ true);
3804 
3805   OS.indent(4) << "}\n";
3806 }
3807 
3808 void Scop::print(raw_ostream &OS) const {
3809   OS.indent(4) << "Function: " << getFunction().getName() << "\n";
3810   OS.indent(4) << "Region: " << getNameStr() << "\n";
3811   OS.indent(4) << "Max Loop Depth:  " << getMaxLoopDepth() << "\n";
3812   OS.indent(4) << "Invariant Accesses: {\n";
3813   for (const auto &IAClass : InvariantEquivClasses) {
3814     const auto &MAs = IAClass.InvariantAccesses;
3815     if (MAs.empty()) {
3816       OS.indent(12) << "Class Pointer: " << *IAClass.IdentifyingPointer << "\n";
3817     } else {
3818       MAs.front()->print(OS);
3819       OS.indent(12) << "Execution Context: " << IAClass.ExecutionContext
3820                     << "\n";
3821     }
3822   }
3823   OS.indent(4) << "}\n";
3824   printContext(OS.indent(4));
3825   printArrayInfo(OS.indent(4));
3826   printAliasAssumptions(OS);
3827   printStatements(OS.indent(4));
3828 }
3829 
3830 void Scop::dump() const { print(dbgs()); }
3831 
3832 isl_ctx *Scop::getIslCtx() const { return IslCtx.get(); }
3833 
3834 __isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB,
3835                                  bool NonNegative) {
3836   // First try to use the SCEVAffinator to generate a piecewise defined
3837   // affine function from @p E in the context of @p BB. If that tasks becomes to
3838   // complex the affinator might return a nullptr. In such a case we invalidate
3839   // the SCoP and return a dummy value. This way we do not need to add error
3840   // handling cdoe to all users of this function.
3841   auto PWAC = Affinator.getPwAff(E, BB);
3842   if (PWAC.first) {
3843     // TODO: We could use a heuristic and either use:
3844     //         SCEVAffinator::takeNonNegativeAssumption
3845     //       or
3846     //         SCEVAffinator::interpretAsUnsigned
3847     //       to deal with unsigned or "NonNegative" SCEVs.
3848     if (NonNegative)
3849       Affinator.takeNonNegativeAssumption(PWAC);
3850     return PWAC;
3851   }
3852 
3853   auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
3854   invalidate(COMPLEXITY, DL);
3855   return Affinator.getPwAff(SE->getZero(E->getType()), BB);
3856 }
3857 
3858 __isl_give isl_union_set *Scop::getDomains() const {
3859   isl_union_set *Domain = isl_union_set_empty(getParamSpace());
3860 
3861   for (const ScopStmt &Stmt : *this)
3862     Domain = isl_union_set_add_set(Domain, Stmt.getDomain());
3863 
3864   return Domain;
3865 }
3866 
3867 __isl_give isl_pw_aff *Scop::getPwAffOnly(const SCEV *E, BasicBlock *BB) {
3868   PWACtx PWAC = getPwAff(E, BB);
3869   isl_set_free(PWAC.second);
3870   return PWAC.first;
3871 }
3872 
3873 __isl_give isl_union_map *
3874 Scop::getAccessesOfType(std::function<bool(MemoryAccess &)> Predicate) {
3875   isl_union_map *Accesses = isl_union_map_empty(getParamSpace());
3876 
3877   for (ScopStmt &Stmt : *this) {
3878     for (MemoryAccess *MA : Stmt) {
3879       if (!Predicate(*MA))
3880         continue;
3881 
3882       isl_set *Domain = Stmt.getDomain();
3883       isl_map *AccessDomain = MA->getAccessRelation();
3884       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
3885       Accesses = isl_union_map_add_map(Accesses, AccessDomain);
3886     }
3887   }
3888   return isl_union_map_coalesce(Accesses);
3889 }
3890 
3891 __isl_give isl_union_map *Scop::getMustWrites() {
3892   return getAccessesOfType([](MemoryAccess &MA) { return MA.isMustWrite(); });
3893 }
3894 
3895 __isl_give isl_union_map *Scop::getMayWrites() {
3896   return getAccessesOfType([](MemoryAccess &MA) { return MA.isMayWrite(); });
3897 }
3898 
3899 __isl_give isl_union_map *Scop::getWrites() {
3900   return getAccessesOfType([](MemoryAccess &MA) { return MA.isWrite(); });
3901 }
3902 
3903 __isl_give isl_union_map *Scop::getReads() {
3904   return getAccessesOfType([](MemoryAccess &MA) { return MA.isRead(); });
3905 }
3906 
3907 __isl_give isl_union_map *Scop::getAccesses() {
3908   return getAccessesOfType([](MemoryAccess &MA) { return true; });
3909 }
3910 
3911 __isl_give isl_union_map *Scop::getSchedule() const {
3912   auto *Tree = getScheduleTree();
3913   auto *S = isl_schedule_get_map(Tree);
3914   isl_schedule_free(Tree);
3915   return S;
3916 }
3917 
3918 __isl_give isl_schedule *Scop::getScheduleTree() const {
3919   return isl_schedule_intersect_domain(isl_schedule_copy(Schedule),
3920                                        getDomains());
3921 }
3922 
3923 void Scop::setSchedule(__isl_take isl_union_map *NewSchedule) {
3924   auto *S = isl_schedule_from_domain(getDomains());
3925   S = isl_schedule_insert_partial_schedule(
3926       S, isl_multi_union_pw_aff_from_union_map(NewSchedule));
3927   isl_schedule_free(Schedule);
3928   Schedule = S;
3929 }
3930 
3931 void Scop::setScheduleTree(__isl_take isl_schedule *NewSchedule) {
3932   isl_schedule_free(Schedule);
3933   Schedule = NewSchedule;
3934 }
3935 
3936 bool Scop::restrictDomains(__isl_take isl_union_set *Domain) {
3937   bool Changed = false;
3938   for (ScopStmt &Stmt : *this) {
3939     isl_union_set *StmtDomain = isl_union_set_from_set(Stmt.getDomain());
3940     isl_union_set *NewStmtDomain = isl_union_set_intersect(
3941         isl_union_set_copy(StmtDomain), isl_union_set_copy(Domain));
3942 
3943     if (isl_union_set_is_subset(StmtDomain, NewStmtDomain)) {
3944       isl_union_set_free(StmtDomain);
3945       isl_union_set_free(NewStmtDomain);
3946       continue;
3947     }
3948 
3949     Changed = true;
3950 
3951     isl_union_set_free(StmtDomain);
3952     NewStmtDomain = isl_union_set_coalesce(NewStmtDomain);
3953 
3954     if (isl_union_set_is_empty(NewStmtDomain)) {
3955       Stmt.restrictDomain(isl_set_empty(Stmt.getDomainSpace()));
3956       isl_union_set_free(NewStmtDomain);
3957     } else
3958       Stmt.restrictDomain(isl_set_from_union_set(NewStmtDomain));
3959   }
3960   isl_union_set_free(Domain);
3961   return Changed;
3962 }
3963 
3964 ScalarEvolution *Scop::getSE() const { return SE; }
3965 
3966 struct MapToDimensionDataTy {
3967   int N;
3968   isl_union_pw_multi_aff *Res;
3969 };
3970 
3971 // Create a function that maps the elements of 'Set' to its N-th dimension and
3972 // add it to User->Res.
3973 //
3974 // @param Set        The input set.
3975 // @param User->N    The dimension to map to.
3976 // @param User->Res  The isl_union_pw_multi_aff to which to add the result.
3977 //
3978 // @returns   isl_stat_ok if no error occured, othewise isl_stat_error.
3979 static isl_stat mapToDimension_AddSet(__isl_take isl_set *Set, void *User) {
3980   struct MapToDimensionDataTy *Data = (struct MapToDimensionDataTy *)User;
3981   int Dim;
3982   isl_space *Space;
3983   isl_pw_multi_aff *PMA;
3984 
3985   Dim = isl_set_dim(Set, isl_dim_set);
3986   Space = isl_set_get_space(Set);
3987   PMA = isl_pw_multi_aff_project_out_map(Space, isl_dim_set, Data->N,
3988                                          Dim - Data->N);
3989   if (Data->N > 1)
3990     PMA = isl_pw_multi_aff_drop_dims(PMA, isl_dim_out, 0, Data->N - 1);
3991   Data->Res = isl_union_pw_multi_aff_add_pw_multi_aff(Data->Res, PMA);
3992 
3993   isl_set_free(Set);
3994 
3995   return isl_stat_ok;
3996 }
3997 
3998 // Create an isl_multi_union_aff that defines an identity mapping from the
3999 // elements of USet to their N-th dimension.
4000 //
4001 // # Example:
4002 //
4003 //            Domain: { A[i,j]; B[i,j,k] }
4004 //                 N: 1
4005 //
4006 // Resulting Mapping: { {A[i,j] -> [(j)]; B[i,j,k] -> [(j)] }
4007 //
4008 // @param USet   A union set describing the elements for which to generate a
4009 //               mapping.
4010 // @param N      The dimension to map to.
4011 // @returns      A mapping from USet to its N-th dimension.
4012 static __isl_give isl_multi_union_pw_aff *
4013 mapToDimension(__isl_take isl_union_set *USet, int N) {
4014   assert(N >= 0);
4015   assert(USet);
4016   assert(!isl_union_set_is_empty(USet));
4017 
4018   struct MapToDimensionDataTy Data;
4019 
4020   auto *Space = isl_union_set_get_space(USet);
4021   auto *PwAff = isl_union_pw_multi_aff_empty(Space);
4022 
4023   Data = {N, PwAff};
4024 
4025   auto Res = isl_union_set_foreach_set(USet, &mapToDimension_AddSet, &Data);
4026   (void)Res;
4027 
4028   assert(Res == isl_stat_ok);
4029 
4030   isl_union_set_free(USet);
4031   return isl_multi_union_pw_aff_from_union_pw_multi_aff(Data.Res);
4032 }
4033 
4034 void Scop::addScopStmt(BasicBlock *BB, Region *R) {
4035   if (BB) {
4036     Stmts.emplace_back(*this, *BB);
4037     auto *Stmt = &Stmts.back();
4038     StmtMap[BB] = Stmt;
4039   } else {
4040     assert(R && "Either basic block or a region expected.");
4041     Stmts.emplace_back(*this, *R);
4042     auto *Stmt = &Stmts.back();
4043     for (BasicBlock *BB : R->blocks())
4044       StmtMap[BB] = Stmt;
4045   }
4046 }
4047 
4048 void Scop::buildSchedule(LoopInfo &LI) {
4049   Loop *L = getLoopSurroundingScop(*this, LI);
4050   LoopStackTy LoopStack({LoopStackElementTy(L, nullptr, 0)});
4051   buildSchedule(getRegion().getNode(), LoopStack, LI);
4052   assert(LoopStack.size() == 1 && LoopStack.back().L == L);
4053   Schedule = LoopStack[0].Schedule;
4054 }
4055 
4056 /// To generate a schedule for the elements in a Region we traverse the Region
4057 /// in reverse-post-order and add the contained RegionNodes in traversal order
4058 /// to the schedule of the loop that is currently at the top of the LoopStack.
4059 /// For loop-free codes, this results in a correct sequential ordering.
4060 ///
4061 /// Example:
4062 ///           bb1(0)
4063 ///         /     \.
4064 ///      bb2(1)   bb3(2)
4065 ///         \    /  \.
4066 ///          bb4(3)  bb5(4)
4067 ///             \   /
4068 ///              bb6(5)
4069 ///
4070 /// Including loops requires additional processing. Whenever a loop header is
4071 /// encountered, the corresponding loop is added to the @p LoopStack. Starting
4072 /// from an empty schedule, we first process all RegionNodes that are within
4073 /// this loop and complete the sequential schedule at this loop-level before
4074 /// processing about any other nodes. To implement this
4075 /// loop-nodes-first-processing, the reverse post-order traversal is
4076 /// insufficient. Hence, we additionally check if the traversal yields
4077 /// sub-regions or blocks that are outside the last loop on the @p LoopStack.
4078 /// These region-nodes are then queue and only traverse after the all nodes
4079 /// within the current loop have been processed.
4080 void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack, LoopInfo &LI) {
4081   Loop *OuterScopLoop = getLoopSurroundingScop(*this, LI);
4082 
4083   ReversePostOrderTraversal<Region *> RTraversal(R);
4084   std::deque<RegionNode *> WorkList(RTraversal.begin(), RTraversal.end());
4085   std::deque<RegionNode *> DelayList;
4086   bool LastRNWaiting = false;
4087 
4088   // Iterate over the region @p R in reverse post-order but queue
4089   // sub-regions/blocks iff they are not part of the last encountered but not
4090   // completely traversed loop. The variable LastRNWaiting is a flag to indicate
4091   // that we queued the last sub-region/block from the reverse post-order
4092   // iterator. If it is set we have to explore the next sub-region/block from
4093   // the iterator (if any) to guarantee progress. If it is not set we first try
4094   // the next queued sub-region/blocks.
4095   while (!WorkList.empty() || !DelayList.empty()) {
4096     RegionNode *RN;
4097 
4098     if ((LastRNWaiting && !WorkList.empty()) || DelayList.size() == 0) {
4099       RN = WorkList.front();
4100       WorkList.pop_front();
4101       LastRNWaiting = false;
4102     } else {
4103       RN = DelayList.front();
4104       DelayList.pop_front();
4105     }
4106 
4107     Loop *L = getRegionNodeLoop(RN, LI);
4108     if (!contains(L))
4109       L = OuterScopLoop;
4110 
4111     Loop *LastLoop = LoopStack.back().L;
4112     if (LastLoop != L) {
4113       if (LastLoop && !LastLoop->contains(L)) {
4114         LastRNWaiting = true;
4115         DelayList.push_back(RN);
4116         continue;
4117       }
4118       LoopStack.push_back({L, nullptr, 0});
4119     }
4120     buildSchedule(RN, LoopStack, LI);
4121   }
4122 
4123   return;
4124 }
4125 
4126 void Scop::buildSchedule(RegionNode *RN, LoopStackTy &LoopStack, LoopInfo &LI) {
4127 
4128   if (RN->isSubRegion()) {
4129     auto *LocalRegion = RN->getNodeAs<Region>();
4130     if (!isNonAffineSubRegion(LocalRegion)) {
4131       buildSchedule(LocalRegion, LoopStack, LI);
4132       return;
4133     }
4134   }
4135 
4136   auto &LoopData = LoopStack.back();
4137   LoopData.NumBlocksProcessed += getNumBlocksInRegionNode(RN);
4138 
4139   if (auto *Stmt = getStmtFor(RN)) {
4140     auto *UDomain = isl_union_set_from_set(Stmt->getDomain());
4141     auto *StmtSchedule = isl_schedule_from_domain(UDomain);
4142     LoopData.Schedule = combineInSequence(LoopData.Schedule, StmtSchedule);
4143   }
4144 
4145   // Check if we just processed the last node in this loop. If we did, finalize
4146   // the loop by:
4147   //
4148   //   - adding new schedule dimensions
4149   //   - folding the resulting schedule into the parent loop schedule
4150   //   - dropping the loop schedule from the LoopStack.
4151   //
4152   // Then continue to check surrounding loops, which might also have been
4153   // completed by this node.
4154   while (LoopData.L &&
4155          LoopData.NumBlocksProcessed == LoopData.L->getNumBlocks()) {
4156     auto *Schedule = LoopData.Schedule;
4157     auto NumBlocksProcessed = LoopData.NumBlocksProcessed;
4158 
4159     LoopStack.pop_back();
4160     auto &NextLoopData = LoopStack.back();
4161 
4162     if (Schedule) {
4163       auto *Domain = isl_schedule_get_domain(Schedule);
4164       auto *MUPA = mapToDimension(Domain, LoopStack.size());
4165       Schedule = isl_schedule_insert_partial_schedule(Schedule, MUPA);
4166       NextLoopData.Schedule =
4167           combineInSequence(NextLoopData.Schedule, Schedule);
4168     }
4169 
4170     NextLoopData.NumBlocksProcessed += NumBlocksProcessed;
4171     LoopData = NextLoopData;
4172   }
4173 }
4174 
4175 ScopStmt *Scop::getStmtFor(BasicBlock *BB) const {
4176   auto StmtMapIt = StmtMap.find(BB);
4177   if (StmtMapIt == StmtMap.end())
4178     return nullptr;
4179   return StmtMapIt->second;
4180 }
4181 
4182 ScopStmt *Scop::getStmtFor(RegionNode *RN) const {
4183   if (RN->isSubRegion())
4184     return getStmtFor(RN->getNodeAs<Region>());
4185   return getStmtFor(RN->getNodeAs<BasicBlock>());
4186 }
4187 
4188 ScopStmt *Scop::getStmtFor(Region *R) const {
4189   ScopStmt *Stmt = getStmtFor(R->getEntry());
4190   assert(!Stmt || Stmt->getRegion() == R);
4191   return Stmt;
4192 }
4193 
4194 int Scop::getRelativeLoopDepth(const Loop *L) const {
4195   Loop *OuterLoop =
4196       L ? R.outermostLoopInRegion(const_cast<Loop *>(L)) : nullptr;
4197   if (!OuterLoop)
4198     return -1;
4199   return L->getLoopDepth() - OuterLoop->getLoopDepth();
4200 }
4201 
4202 ScopArrayInfo *Scop::getArrayInfoByName(const std::string BaseName) {
4203   for (auto &SAI : arrays()) {
4204     if (SAI->getName() == BaseName)
4205       return SAI;
4206   }
4207   return nullptr;
4208 }
4209 
4210 //===----------------------------------------------------------------------===//
4211 void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const {
4212   AU.addRequired<LoopInfoWrapperPass>();
4213   AU.addRequired<RegionInfoPass>();
4214   AU.addRequired<DominatorTreeWrapperPass>();
4215   AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
4216   AU.addRequiredTransitive<ScopDetection>();
4217   AU.addRequired<AAResultsWrapperPass>();
4218   AU.addRequired<AssumptionCacheTracker>();
4219   AU.setPreservesAll();
4220 }
4221 
4222 bool ScopInfoRegionPass::runOnRegion(Region *R, RGPassManager &RGM) {
4223   auto &SD = getAnalysis<ScopDetection>();
4224 
4225   if (!SD.isMaxRegionInScop(*R))
4226     return false;
4227 
4228   Function *F = R->getEntry()->getParent();
4229   auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
4230   auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
4231   auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
4232   auto const &DL = F->getParent()->getDataLayout();
4233   auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
4234   auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*F);
4235 
4236   ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE);
4237   S = SB.getScop(); // take ownership of scop object
4238   return false;
4239 }
4240 
4241 void ScopInfoRegionPass::print(raw_ostream &OS, const Module *) const {
4242   if (S)
4243     S->print(OS);
4244   else
4245     OS << "Invalid Scop!\n";
4246 }
4247 
4248 char ScopInfoRegionPass::ID = 0;
4249 
4250 Pass *polly::createScopInfoRegionPassPass() { return new ScopInfoRegionPass(); }
4251 
4252 INITIALIZE_PASS_BEGIN(ScopInfoRegionPass, "polly-scops",
4253                       "Polly - Create polyhedral description of Scops", false,
4254                       false);
4255 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
4256 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker);
4257 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
4258 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
4259 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
4260 INITIALIZE_PASS_DEPENDENCY(ScopDetection);
4261 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
4262 INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops",
4263                     "Polly - Create polyhedral description of Scops", false,
4264                     false)
4265 
4266 //===----------------------------------------------------------------------===//
4267 void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
4268   AU.addRequired<LoopInfoWrapperPass>();
4269   AU.addRequired<RegionInfoPass>();
4270   AU.addRequired<DominatorTreeWrapperPass>();
4271   AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
4272   AU.addRequiredTransitive<ScopDetection>();
4273   AU.addRequired<AAResultsWrapperPass>();
4274   AU.addRequired<AssumptionCacheTracker>();
4275   AU.setPreservesAll();
4276 }
4277 
4278 bool ScopInfoWrapperPass::runOnFunction(Function &F) {
4279   auto &SD = getAnalysis<ScopDetection>();
4280 
4281   auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
4282   auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
4283   auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
4284   auto const &DL = F.getParent()->getDataLayout();
4285   auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
4286   auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
4287 
4288   /// Create polyhedral descripton of scops for all the valid regions of a
4289   /// function.
4290   for (auto &It : SD) {
4291     Region *R = const_cast<Region *>(It);
4292     if (!SD.isMaxRegionInScop(*R))
4293       continue;
4294 
4295     ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE);
4296     std::unique_ptr<Scop> S = SB.getScop();
4297     if (!S)
4298       continue;
4299     bool Inserted =
4300         RegionToScopMap.insert(std::make_pair(R, std::move(S))).second;
4301     assert(Inserted && "Building Scop for the same region twice!");
4302     (void)Inserted;
4303   }
4304   return false;
4305 }
4306 
4307 void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const {
4308   for (auto &It : RegionToScopMap) {
4309     if (It.second)
4310       It.second->print(OS);
4311     else
4312       OS << "Invalid Scop!\n";
4313   }
4314 }
4315 
4316 char ScopInfoWrapperPass::ID = 0;
4317 
4318 Pass *polly::createScopInfoWrapperPassPass() {
4319   return new ScopInfoWrapperPass();
4320 }
4321 
4322 INITIALIZE_PASS_BEGIN(
4323     ScopInfoWrapperPass, "polly-function-scops",
4324     "Polly - Create polyhedral description of all Scops of a function", false,
4325     false);
4326 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
4327 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker);
4328 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
4329 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
4330 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
4331 INITIALIZE_PASS_DEPENDENCY(ScopDetection);
4332 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
4333 INITIALIZE_PASS_END(
4334     ScopInfoWrapperPass, "polly-function-scops",
4335     "Polly - Create polyhedral description of all Scops of a function", false,
4336     false)
4337