1 //===- ScopInfo.cpp -------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Create a polyhedral description for a static control flow region.
10 //
11 // The pass creates a polyhedral description of the Scops detected by the Scop
12 // detection derived from their LLVM-IR code.
13 //
14 // This representation is shared among several tools in the polyhedral
15 // community, which are e.g. Cloog, Pluto, Loopo, Graphite.
16 //
17 //===----------------------------------------------------------------------===//
18 
19 #include "polly/ScopInfo.h"
20 #include "polly/LinkAllPasses.h"
21 #include "polly/Options.h"
22 #include "polly/ScopBuilder.h"
23 #include "polly/ScopDetection.h"
24 #include "polly/Support/GICHelper.h"
25 #include "polly/Support/ISLOStream.h"
26 #include "polly/Support/ISLTools.h"
27 #include "polly/Support/SCEVAffinator.h"
28 #include "polly/Support/SCEVValidator.h"
29 #include "polly/Support/ScopHelper.h"
30 #include "llvm/ADT/APInt.h"
31 #include "llvm/ADT/ArrayRef.h"
32 #include "llvm/ADT/PostOrderIterator.h"
33 #include "llvm/ADT/SmallPtrSet.h"
34 #include "llvm/ADT/SmallSet.h"
35 #include "llvm/ADT/Statistic.h"
36 #include "llvm/Analysis/AliasAnalysis.h"
37 #include "llvm/Analysis/AssumptionCache.h"
38 #include "llvm/Analysis/Loads.h"
39 #include "llvm/Analysis/LoopInfo.h"
40 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
41 #include "llvm/Analysis/RegionInfo.h"
42 #include "llvm/Analysis/RegionIterator.h"
43 #include "llvm/Analysis/ScalarEvolution.h"
44 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
45 #include "llvm/IR/BasicBlock.h"
46 #include "llvm/IR/ConstantRange.h"
47 #include "llvm/IR/DataLayout.h"
48 #include "llvm/IR/DebugLoc.h"
49 #include "llvm/IR/Dominators.h"
50 #include "llvm/IR/Function.h"
51 #include "llvm/IR/InstrTypes.h"
52 #include "llvm/IR/Instruction.h"
53 #include "llvm/IR/Instructions.h"
54 #include "llvm/IR/Module.h"
55 #include "llvm/IR/PassManager.h"
56 #include "llvm/IR/Type.h"
57 #include "llvm/IR/Value.h"
58 #include "llvm/Support/Compiler.h"
59 #include "llvm/Support/Debug.h"
60 #include "llvm/Support/ErrorHandling.h"
61 #include "llvm/Support/raw_ostream.h"
62 #include "isl/aff.h"
63 #include "isl/local_space.h"
64 #include "isl/map.h"
65 #include "isl/options.h"
66 #include "isl/set.h"
67 #include <cassert>
68 
69 using namespace llvm;
70 using namespace polly;
71 
72 #define DEBUG_TYPE "polly-scops"
73 
74 STATISTIC(AssumptionsAliasing, "Number of aliasing assumptions taken.");
75 STATISTIC(AssumptionsInbounds, "Number of inbounds assumptions taken.");
76 STATISTIC(AssumptionsWrapping, "Number of wrapping assumptions taken.");
77 STATISTIC(AssumptionsUnsigned, "Number of unsigned assumptions taken.");
78 STATISTIC(AssumptionsComplexity, "Number of too complex SCoPs.");
79 STATISTIC(AssumptionsUnprofitable, "Number of unprofitable SCoPs.");
80 STATISTIC(AssumptionsErrorBlock, "Number of error block assumptions taken.");
81 STATISTIC(AssumptionsInfiniteLoop, "Number of bounded loop assumptions taken.");
82 STATISTIC(AssumptionsInvariantLoad,
83           "Number of invariant loads assumptions taken.");
84 STATISTIC(AssumptionsDelinearization,
85           "Number of delinearization assumptions taken.");
86 
87 STATISTIC(NumScops, "Number of feasible SCoPs after ScopInfo");
88 STATISTIC(NumLoopsInScop, "Number of loops in scops");
89 STATISTIC(NumBoxedLoops, "Number of boxed loops in SCoPs after ScopInfo");
90 STATISTIC(NumAffineLoops, "Number of affine loops in SCoPs after ScopInfo");
91 
92 STATISTIC(NumScopsDepthZero, "Number of scops with maximal loop depth 0");
93 STATISTIC(NumScopsDepthOne, "Number of scops with maximal loop depth 1");
94 STATISTIC(NumScopsDepthTwo, "Number of scops with maximal loop depth 2");
95 STATISTIC(NumScopsDepthThree, "Number of scops with maximal loop depth 3");
96 STATISTIC(NumScopsDepthFour, "Number of scops with maximal loop depth 4");
97 STATISTIC(NumScopsDepthFive, "Number of scops with maximal loop depth 5");
98 STATISTIC(NumScopsDepthLarger,
99           "Number of scops with maximal loop depth 6 and larger");
100 STATISTIC(MaxNumLoopsInScop, "Maximal number of loops in scops");
101 
102 STATISTIC(NumValueWrites, "Number of scalar value writes after ScopInfo");
103 STATISTIC(
104     NumValueWritesInLoops,
105     "Number of scalar value writes nested in affine loops after ScopInfo");
106 STATISTIC(NumPHIWrites, "Number of scalar phi writes after ScopInfo");
107 STATISTIC(NumPHIWritesInLoops,
108           "Number of scalar phi writes nested in affine loops after ScopInfo");
109 STATISTIC(NumSingletonWrites, "Number of singleton writes after ScopInfo");
110 STATISTIC(NumSingletonWritesInLoops,
111           "Number of singleton writes nested in affine loops after ScopInfo");
112 
113 // The maximal number of basic sets we allow during domain construction to
114 // be created. More complex scops will result in very high compile time and
115 // are also unlikely to result in good code
116 static int const MaxDisjunctsInDomain = 20;
117 
118 // The number of disjunct in the context after which we stop to add more
119 // disjuncts. This parameter is there to avoid exponential growth in the
120 // number of disjunct when adding non-convex sets to the context.
121 static int const MaxDisjunctsInContext = 4;
122 
123 // The maximal number of dimensions we allow during invariant load construction.
124 // More complex access ranges will result in very high compile time and are also
125 // unlikely to result in good code. This value is very high and should only
126 // trigger for corner cases (e.g., the "dct_luma" function in h264, SPEC2006).
127 static int const MaxDimensionsInAccessRange = 9;
128 
129 static cl::opt<int>
130     OptComputeOut("polly-analysis-computeout",
131                   cl::desc("Bound the scop analysis by a maximal amount of "
132                            "computational steps (0 means no bound)"),
133                   cl::Hidden, cl::init(800000), cl::ZeroOrMore,
134                   cl::cat(PollyCategory));
135 
136 static cl::opt<bool> PollyRemarksMinimal(
137     "polly-remarks-minimal",
138     cl::desc("Do not emit remarks about assumptions that are known"),
139     cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::cat(PollyCategory));
140 
141 static cl::opt<int> RunTimeChecksMaxAccessDisjuncts(
142     "polly-rtc-max-array-disjuncts",
143     cl::desc("The maximal number of disjunts allowed in memory accesses to "
144              "to build RTCs."),
145     cl::Hidden, cl::ZeroOrMore, cl::init(8), cl::cat(PollyCategory));
146 
147 static cl::opt<unsigned> RunTimeChecksMaxParameters(
148     "polly-rtc-max-parameters",
149     cl::desc("The maximal number of parameters allowed in RTCs."), cl::Hidden,
150     cl::ZeroOrMore, cl::init(8), cl::cat(PollyCategory));
151 
152 static cl::opt<unsigned> RunTimeChecksMaxArraysPerGroup(
153     "polly-rtc-max-arrays-per-group",
154     cl::desc("The maximal number of arrays to compare in each alias group."),
155     cl::Hidden, cl::ZeroOrMore, cl::init(20), cl::cat(PollyCategory));
156 
157 static cl::opt<std::string> UserContextStr(
158     "polly-context", cl::value_desc("isl parameter set"),
159     cl::desc("Provide additional constraints on the context parameters"),
160     cl::init(""), cl::cat(PollyCategory));
161 
162 static cl::opt<bool>
163     IslOnErrorAbort("polly-on-isl-error-abort",
164                     cl::desc("Abort if an isl error is encountered"),
165                     cl::init(true), cl::cat(PollyCategory));
166 
167 static cl::opt<bool> PollyPreciseInbounds(
168     "polly-precise-inbounds",
169     cl::desc("Take more precise inbounds assumptions (do not scale well)"),
170     cl::Hidden, cl::init(false), cl::cat(PollyCategory));
171 
172 static cl::opt<bool>
173     PollyIgnoreInbounds("polly-ignore-inbounds",
174                         cl::desc("Do not take inbounds assumptions at all"),
175                         cl::Hidden, cl::init(false), cl::cat(PollyCategory));
176 
177 static cl::opt<bool> PollyIgnoreParamBounds(
178     "polly-ignore-parameter-bounds",
179     cl::desc(
180         "Do not add parameter bounds and do no gist simplify sets accordingly"),
181     cl::Hidden, cl::init(false), cl::cat(PollyCategory));
182 
183 static cl::opt<bool> PollyAllowDereferenceOfAllFunctionParams(
184     "polly-allow-dereference-of-all-function-parameters",
185     cl::desc(
186         "Treat all parameters to functions that are pointers as dereferencible."
187         " This is useful for invariant load hoisting, since we can generate"
188         " less runtime checks. This is only valid if all pointers to functions"
189         " are always initialized, so that Polly can choose to hoist"
190         " their loads. "),
191     cl::Hidden, cl::init(false), cl::cat(PollyCategory));
192 
193 static cl::opt<bool> PollyPreciseFoldAccesses(
194     "polly-precise-fold-accesses",
195     cl::desc("Fold memory accesses to model more possible delinearizations "
196              "(does not scale well)"),
197     cl::Hidden, cl::init(false), cl::cat(PollyCategory));
198 
199 bool polly::UseInstructionNames;
200 
201 static cl::opt<bool, true> XUseInstructionNames(
202     "polly-use-llvm-names",
203     cl::desc("Use LLVM-IR names when deriving statement names"),
204     cl::location(UseInstructionNames), cl::Hidden, cl::init(false),
205     cl::ZeroOrMore, cl::cat(PollyCategory));
206 
207 static cl::opt<bool> PollyPrintInstructions(
208     "polly-print-instructions", cl::desc("Output instructions per ScopStmt"),
209     cl::Hidden, cl::Optional, cl::init(false), cl::cat(PollyCategory));
210 
211 //===----------------------------------------------------------------------===//
212 
213 // Create a sequence of two schedules. Either argument may be null and is
214 // interpreted as the empty schedule. Can also return null if both schedules are
215 // empty.
216 static isl::schedule combineInSequence(isl::schedule Prev, isl::schedule Succ) {
217   if (!Prev)
218     return Succ;
219   if (!Succ)
220     return Prev;
221 
222   return Prev.sequence(Succ);
223 }
224 
225 static isl::set addRangeBoundsToSet(isl::set S, const ConstantRange &Range,
226                                     int dim, isl::dim type) {
227   isl::val V;
228   isl::ctx Ctx = S.get_ctx();
229 
230   // The upper and lower bound for a parameter value is derived either from
231   // the data type of the parameter or from the - possibly more restrictive -
232   // range metadata.
233   V = valFromAPInt(Ctx.get(), Range.getSignedMin(), true);
234   S = S.lower_bound_val(type, dim, V);
235   V = valFromAPInt(Ctx.get(), Range.getSignedMax(), true);
236   S = S.upper_bound_val(type, dim, V);
237 
238   if (Range.isFullSet())
239     return S;
240 
241   if (S.n_basic_set() > MaxDisjunctsInContext)
242     return S;
243 
244   // In case of signed wrapping, we can refine the set of valid values by
245   // excluding the part not covered by the wrapping range.
246   if (Range.isSignWrappedSet()) {
247     V = valFromAPInt(Ctx.get(), Range.getLower(), true);
248     isl::set SLB = S.lower_bound_val(type, dim, V);
249 
250     V = valFromAPInt(Ctx.get(), Range.getUpper(), true);
251     V = V.sub_ui(1);
252     isl::set SUB = S.upper_bound_val(type, dim, V);
253     S = SLB.unite(SUB);
254   }
255 
256   return S;
257 }
258 
259 static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) {
260   LoadInst *BasePtrLI = dyn_cast<LoadInst>(BasePtr);
261   if (!BasePtrLI)
262     return nullptr;
263 
264   if (!S->contains(BasePtrLI))
265     return nullptr;
266 
267   ScalarEvolution &SE = *S->getSE();
268 
269   auto *OriginBaseSCEV =
270       SE.getPointerBase(SE.getSCEV(BasePtrLI->getPointerOperand()));
271   if (!OriginBaseSCEV)
272     return nullptr;
273 
274   auto *OriginBaseSCEVUnknown = dyn_cast<SCEVUnknown>(OriginBaseSCEV);
275   if (!OriginBaseSCEVUnknown)
276     return nullptr;
277 
278   return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue(),
279                              MemoryKind::Array);
280 }
281 
282 ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl::ctx Ctx,
283                              ArrayRef<const SCEV *> Sizes, MemoryKind Kind,
284                              const DataLayout &DL, Scop *S,
285                              const char *BaseName)
286     : BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), DL(DL), S(*S) {
287   std::string BasePtrName =
288       BaseName ? BaseName
289                : getIslCompatibleName("MemRef", BasePtr, S->getNextArrayIdx(),
290                                       Kind == MemoryKind::PHI ? "__phi" : "",
291                                       UseInstructionNames);
292   Id = isl::id::alloc(Ctx, BasePtrName, this);
293 
294   updateSizes(Sizes);
295 
296   if (!BasePtr || Kind != MemoryKind::Array) {
297     BasePtrOriginSAI = nullptr;
298     return;
299   }
300 
301   BasePtrOriginSAI = identifyBasePtrOriginSAI(S, BasePtr);
302   if (BasePtrOriginSAI)
303     const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
304 }
305 
306 ScopArrayInfo::~ScopArrayInfo() = default;
307 
308 isl::space ScopArrayInfo::getSpace() const {
309   auto Space = isl::space(Id.get_ctx(), 0, getNumberOfDimensions());
310   Space = Space.set_tuple_id(isl::dim::set, Id);
311   return Space;
312 }
313 
314 bool ScopArrayInfo::isReadOnly() {
315   isl::union_set WriteSet = S.getWrites().range();
316   isl::space Space = getSpace();
317   WriteSet = WriteSet.extract_set(Space);
318 
319   return bool(WriteSet.is_empty());
320 }
321 
322 bool ScopArrayInfo::isCompatibleWith(const ScopArrayInfo *Array) const {
323   if (Array->getElementType() != getElementType())
324     return false;
325 
326   if (Array->getNumberOfDimensions() != getNumberOfDimensions())
327     return false;
328 
329   for (unsigned i = 0; i < getNumberOfDimensions(); i++)
330     if (Array->getDimensionSize(i) != getDimensionSize(i))
331       return false;
332 
333   return true;
334 }
335 
336 void ScopArrayInfo::updateElementType(Type *NewElementType) {
337   if (NewElementType == ElementType)
338     return;
339 
340   auto OldElementSize = DL.getTypeAllocSizeInBits(ElementType);
341   auto NewElementSize = DL.getTypeAllocSizeInBits(NewElementType);
342 
343   if (NewElementSize == OldElementSize || NewElementSize == 0)
344     return;
345 
346   if (NewElementSize % OldElementSize == 0 && NewElementSize < OldElementSize) {
347     ElementType = NewElementType;
348   } else {
349     auto GCD = GreatestCommonDivisor64(NewElementSize, OldElementSize);
350     ElementType = IntegerType::get(ElementType->getContext(), GCD);
351   }
352 }
353 
354 /// Make the ScopArrayInfo model a Fortran Array
355 void ScopArrayInfo::applyAndSetFAD(Value *FAD) {
356   assert(FAD && "got invalid Fortran array descriptor");
357   if (this->FAD) {
358     assert(this->FAD == FAD &&
359            "receiving different array descriptors for same array");
360     return;
361   }
362 
363   assert(DimensionSizesPw.size() > 0 && !DimensionSizesPw[0]);
364   assert(!this->FAD);
365   this->FAD = FAD;
366 
367   isl::space Space(S.getIslCtx(), 1, 0);
368 
369   std::string param_name = getName();
370   param_name += "_fortranarr_size";
371   isl::id IdPwAff = isl::id::alloc(S.getIslCtx(), param_name, this);
372 
373   Space = Space.set_dim_id(isl::dim::param, 0, IdPwAff);
374   isl::pw_aff PwAff =
375       isl::aff::var_on_domain(isl::local_space(Space), isl::dim::param, 0);
376 
377   DimensionSizesPw[0] = PwAff;
378 }
379 
380 bool ScopArrayInfo::updateSizes(ArrayRef<const SCEV *> NewSizes,
381                                 bool CheckConsistency) {
382   int SharedDims = std::min(NewSizes.size(), DimensionSizes.size());
383   int ExtraDimsNew = NewSizes.size() - SharedDims;
384   int ExtraDimsOld = DimensionSizes.size() - SharedDims;
385 
386   if (CheckConsistency) {
387     for (int i = 0; i < SharedDims; i++) {
388       auto *NewSize = NewSizes[i + ExtraDimsNew];
389       auto *KnownSize = DimensionSizes[i + ExtraDimsOld];
390       if (NewSize && KnownSize && NewSize != KnownSize)
391         return false;
392     }
393 
394     if (DimensionSizes.size() >= NewSizes.size())
395       return true;
396   }
397 
398   DimensionSizes.clear();
399   DimensionSizes.insert(DimensionSizes.begin(), NewSizes.begin(),
400                         NewSizes.end());
401   DimensionSizesPw.clear();
402   for (const SCEV *Expr : DimensionSizes) {
403     if (!Expr) {
404       DimensionSizesPw.push_back(nullptr);
405       continue;
406     }
407     isl::pw_aff Size = S.getPwAffOnly(Expr);
408     DimensionSizesPw.push_back(Size);
409   }
410   return true;
411 }
412 
413 std::string ScopArrayInfo::getName() const { return Id.get_name(); }
414 
415 int ScopArrayInfo::getElemSizeInBytes() const {
416   return DL.getTypeAllocSize(ElementType);
417 }
418 
419 isl::id ScopArrayInfo::getBasePtrId() const { return Id; }
420 
421 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
422 LLVM_DUMP_METHOD void ScopArrayInfo::dump() const { print(errs()); }
423 #endif
424 
425 void ScopArrayInfo::print(raw_ostream &OS, bool SizeAsPwAff) const {
426   OS.indent(8) << *getElementType() << " " << getName();
427   unsigned u = 0;
428   // If this is a Fortran array, then we can print the outermost dimension
429   // as a isl_pw_aff even though there is no SCEV information.
430   bool IsOutermostSizeKnown = SizeAsPwAff && FAD;
431 
432   if (!IsOutermostSizeKnown && getNumberOfDimensions() > 0 &&
433       !getDimensionSize(0)) {
434     OS << "[*]";
435     u++;
436   }
437   for (; u < getNumberOfDimensions(); u++) {
438     OS << "[";
439 
440     if (SizeAsPwAff) {
441       isl::pw_aff Size = getDimensionSizePw(u);
442       OS << " " << Size << " ";
443     } else {
444       OS << *getDimensionSize(u);
445     }
446 
447     OS << "]";
448   }
449 
450   OS << ";";
451 
452   if (BasePtrOriginSAI)
453     OS << " [BasePtrOrigin: " << BasePtrOriginSAI->getName() << "]";
454 
455   OS << " // Element size " << getElemSizeInBytes() << "\n";
456 }
457 
458 const ScopArrayInfo *
459 ScopArrayInfo::getFromAccessFunction(isl::pw_multi_aff PMA) {
460   isl::id Id = PMA.get_tuple_id(isl::dim::out);
461   assert(!Id.is_null() && "Output dimension didn't have an ID");
462   return getFromId(Id);
463 }
464 
465 const ScopArrayInfo *ScopArrayInfo::getFromId(isl::id Id) {
466   void *User = Id.get_user();
467   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
468   return SAI;
469 }
470 
471 void MemoryAccess::wrapConstantDimensions() {
472   auto *SAI = getScopArrayInfo();
473   isl::space ArraySpace = SAI->getSpace();
474   isl::ctx Ctx = ArraySpace.get_ctx();
475   unsigned DimsArray = SAI->getNumberOfDimensions();
476 
477   isl::multi_aff DivModAff = isl::multi_aff::identity(
478       ArraySpace.map_from_domain_and_range(ArraySpace));
479   isl::local_space LArraySpace = isl::local_space(ArraySpace);
480 
481   // Begin with last dimension, to iteratively carry into higher dimensions.
482   for (int i = DimsArray - 1; i > 0; i--) {
483     auto *DimSize = SAI->getDimensionSize(i);
484     auto *DimSizeCst = dyn_cast<SCEVConstant>(DimSize);
485 
486     // This transformation is not applicable to dimensions with dynamic size.
487     if (!DimSizeCst)
488       continue;
489 
490     // This transformation is not applicable to dimensions of size zero.
491     if (DimSize->isZero())
492       continue;
493 
494     isl::val DimSizeVal =
495         valFromAPInt(Ctx.get(), DimSizeCst->getAPInt(), false);
496     isl::aff Var = isl::aff::var_on_domain(LArraySpace, isl::dim::set, i);
497     isl::aff PrevVar =
498         isl::aff::var_on_domain(LArraySpace, isl::dim::set, i - 1);
499 
500     // Compute: index % size
501     // Modulo must apply in the divide of the previous iteration, if any.
502     isl::aff Modulo = Var.mod(DimSizeVal);
503     Modulo = Modulo.pullback(DivModAff);
504 
505     // Compute: floor(index / size)
506     isl::aff Divide = Var.div(isl::aff(LArraySpace, DimSizeVal));
507     Divide = Divide.floor();
508     Divide = Divide.add(PrevVar);
509     Divide = Divide.pullback(DivModAff);
510 
511     // Apply Modulo and Divide.
512     DivModAff = DivModAff.set_aff(i, Modulo);
513     DivModAff = DivModAff.set_aff(i - 1, Divide);
514   }
515 
516   // Apply all modulo/divides on the accesses.
517   isl::map Relation = AccessRelation;
518   Relation = Relation.apply_range(isl::map::from_multi_aff(DivModAff));
519   Relation = Relation.detect_equalities();
520   AccessRelation = Relation;
521 }
522 
523 void MemoryAccess::updateDimensionality() {
524   auto *SAI = getScopArrayInfo();
525   isl::space ArraySpace = SAI->getSpace();
526   isl::space AccessSpace = AccessRelation.get_space().range();
527   isl::ctx Ctx = ArraySpace.get_ctx();
528 
529   auto DimsArray = ArraySpace.dim(isl::dim::set);
530   auto DimsAccess = AccessSpace.dim(isl::dim::set);
531   auto DimsMissing = DimsArray - DimsAccess;
532 
533   auto *BB = getStatement()->getEntryBlock();
534   auto &DL = BB->getModule()->getDataLayout();
535   unsigned ArrayElemSize = SAI->getElemSizeInBytes();
536   unsigned ElemBytes = DL.getTypeAllocSize(getElementType());
537 
538   isl::map Map = isl::map::from_domain_and_range(
539       isl::set::universe(AccessSpace), isl::set::universe(ArraySpace));
540 
541   for (unsigned i = 0; i < DimsMissing; i++)
542     Map = Map.fix_si(isl::dim::out, i, 0);
543 
544   for (unsigned i = DimsMissing; i < DimsArray; i++)
545     Map = Map.equate(isl::dim::in, i - DimsMissing, isl::dim::out, i);
546 
547   AccessRelation = AccessRelation.apply_range(Map);
548 
549   // For the non delinearized arrays, divide the access function of the last
550   // subscript by the size of the elements in the array.
551   //
552   // A stride one array access in C expressed as A[i] is expressed in
553   // LLVM-IR as something like A[i * elementsize]. This hides the fact that
554   // two subsequent values of 'i' index two values that are stored next to
555   // each other in memory. By this division we make this characteristic
556   // obvious again. If the base pointer was accessed with offsets not divisible
557   // by the accesses element size, we will have chosen a smaller ArrayElemSize
558   // that divides the offsets of all accesses to this base pointer.
559   if (DimsAccess == 1) {
560     isl::val V = isl::val(Ctx, ArrayElemSize);
561     AccessRelation = AccessRelation.floordiv_val(V);
562   }
563 
564   // We currently do this only if we added at least one dimension, which means
565   // some dimension's indices have not been specified, an indicator that some
566   // index values have been added together.
567   // TODO: Investigate general usefulness; Effect on unit tests is to make index
568   // expressions more complicated.
569   if (DimsMissing)
570     wrapConstantDimensions();
571 
572   if (!isAffine())
573     computeBoundsOnAccessRelation(ArrayElemSize);
574 
575   // Introduce multi-element accesses in case the type loaded by this memory
576   // access is larger than the canonical element type of the array.
577   //
578   // An access ((float *)A)[i] to an array char *A is modeled as
579   // {[i] -> A[o] : 4 i <= o <= 4 i + 3
580   if (ElemBytes > ArrayElemSize) {
581     assert(ElemBytes % ArrayElemSize == 0 &&
582            "Loaded element size should be multiple of canonical element size");
583     isl::map Map = isl::map::from_domain_and_range(
584         isl::set::universe(ArraySpace), isl::set::universe(ArraySpace));
585     for (unsigned i = 0; i < DimsArray - 1; i++)
586       Map = Map.equate(isl::dim::in, i, isl::dim::out, i);
587 
588     isl::constraint C;
589     isl::local_space LS;
590 
591     LS = isl::local_space(Map.get_space());
592     int Num = ElemBytes / getScopArrayInfo()->getElemSizeInBytes();
593 
594     C = isl::constraint::alloc_inequality(LS);
595     C = C.set_constant_val(isl::val(Ctx, Num - 1));
596     C = C.set_coefficient_si(isl::dim::in, DimsArray - 1, 1);
597     C = C.set_coefficient_si(isl::dim::out, DimsArray - 1, -1);
598     Map = Map.add_constraint(C);
599 
600     C = isl::constraint::alloc_inequality(LS);
601     C = C.set_coefficient_si(isl::dim::in, DimsArray - 1, -1);
602     C = C.set_coefficient_si(isl::dim::out, DimsArray - 1, 1);
603     C = C.set_constant_val(isl::val(Ctx, 0));
604     Map = Map.add_constraint(C);
605     AccessRelation = AccessRelation.apply_range(Map);
606   }
607 }
608 
609 const std::string
610 MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
611   switch (RT) {
612   case MemoryAccess::RT_NONE:
613     llvm_unreachable("Requested a reduction operator string for a memory "
614                      "access which isn't a reduction");
615   case MemoryAccess::RT_ADD:
616     return "+";
617   case MemoryAccess::RT_MUL:
618     return "*";
619   case MemoryAccess::RT_BOR:
620     return "|";
621   case MemoryAccess::RT_BXOR:
622     return "^";
623   case MemoryAccess::RT_BAND:
624     return "&";
625   }
626   llvm_unreachable("Unknown reduction type");
627 }
628 
629 const ScopArrayInfo *MemoryAccess::getOriginalScopArrayInfo() const {
630   isl::id ArrayId = getArrayId();
631   void *User = ArrayId.get_user();
632   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
633   return SAI;
634 }
635 
636 const ScopArrayInfo *MemoryAccess::getLatestScopArrayInfo() const {
637   isl::id ArrayId = getLatestArrayId();
638   void *User = ArrayId.get_user();
639   const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
640   return SAI;
641 }
642 
643 isl::id MemoryAccess::getOriginalArrayId() const {
644   return AccessRelation.get_tuple_id(isl::dim::out);
645 }
646 
647 isl::id MemoryAccess::getLatestArrayId() const {
648   if (!hasNewAccessRelation())
649     return getOriginalArrayId();
650   return NewAccessRelation.get_tuple_id(isl::dim::out);
651 }
652 
653 isl::map MemoryAccess::getAddressFunction() const {
654   return getAccessRelation().lexmin();
655 }
656 
657 isl::pw_multi_aff
658 MemoryAccess::applyScheduleToAccessRelation(isl::union_map USchedule) const {
659   isl::map Schedule, ScheduledAccRel;
660   isl::union_set UDomain;
661 
662   UDomain = getStatement()->getDomain();
663   USchedule = USchedule.intersect_domain(UDomain);
664   Schedule = isl::map::from_union_map(USchedule);
665   ScheduledAccRel = getAddressFunction().apply_domain(Schedule);
666   return isl::pw_multi_aff::from_map(ScheduledAccRel);
667 }
668 
669 isl::map MemoryAccess::getOriginalAccessRelation() const {
670   return AccessRelation;
671 }
672 
673 std::string MemoryAccess::getOriginalAccessRelationStr() const {
674   return AccessRelation.to_str();
675 }
676 
677 isl::space MemoryAccess::getOriginalAccessRelationSpace() const {
678   return AccessRelation.get_space();
679 }
680 
681 isl::map MemoryAccess::getNewAccessRelation() const {
682   return NewAccessRelation;
683 }
684 
685 std::string MemoryAccess::getNewAccessRelationStr() const {
686   return NewAccessRelation.to_str();
687 }
688 
689 std::string MemoryAccess::getAccessRelationStr() const {
690   return getAccessRelation().to_str();
691 }
692 
693 isl::basic_map MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
694   isl::space Space = isl::space(Statement->getIslCtx(), 0, 1);
695   Space = Space.align_params(Statement->getDomainSpace());
696 
697   return isl::basic_map::from_domain_and_range(
698       isl::basic_set::universe(Statement->getDomainSpace()),
699       isl::basic_set::universe(Space));
700 }
701 
702 // Formalize no out-of-bound access assumption
703 //
704 // When delinearizing array accesses we optimistically assume that the
705 // delinearized accesses do not access out of bound locations (the subscript
706 // expression of each array evaluates for each statement instance that is
707 // executed to a value that is larger than zero and strictly smaller than the
708 // size of the corresponding dimension). The only exception is the outermost
709 // dimension for which we do not need to assume any upper bound.  At this point
710 // we formalize this assumption to ensure that at code generation time the
711 // relevant run-time checks can be generated.
712 //
713 // To find the set of constraints necessary to avoid out of bound accesses, we
714 // first build the set of data locations that are not within array bounds. We
715 // then apply the reverse access relation to obtain the set of iterations that
716 // may contain invalid accesses and reduce this set of iterations to the ones
717 // that are actually executed by intersecting them with the domain of the
718 // statement. If we now project out all loop dimensions, we obtain a set of
719 // parameters that may cause statement instances to be executed that may
720 // possibly yield out of bound memory accesses. The complement of these
721 // constraints is the set of constraints that needs to be assumed to ensure such
722 // statement instances are never executed.
723 void MemoryAccess::assumeNoOutOfBound() {
724   if (PollyIgnoreInbounds)
725     return;
726   auto *SAI = getScopArrayInfo();
727   isl::space Space = getOriginalAccessRelationSpace().range();
728   isl::set Outside = isl::set::empty(Space);
729   for (int i = 1, Size = Space.dim(isl::dim::set); i < Size; ++i) {
730     isl::local_space LS(Space);
731     isl::pw_aff Var = isl::pw_aff::var_on_domain(LS, isl::dim::set, i);
732     isl::pw_aff Zero = isl::pw_aff(LS);
733 
734     isl::set DimOutside = Var.lt_set(Zero);
735     isl::pw_aff SizeE = SAI->getDimensionSizePw(i);
736     SizeE = SizeE.add_dims(isl::dim::in, Space.dim(isl::dim::set));
737     SizeE = SizeE.set_tuple_id(isl::dim::in, Space.get_tuple_id(isl::dim::set));
738     DimOutside = DimOutside.unite(SizeE.le_set(Var));
739 
740     Outside = Outside.unite(DimOutside);
741   }
742 
743   Outside = Outside.apply(getAccessRelation().reverse());
744   Outside = Outside.intersect(Statement->getDomain());
745   Outside = Outside.params();
746 
747   // Remove divs to avoid the construction of overly complicated assumptions.
748   // Doing so increases the set of parameter combinations that are assumed to
749   // not appear. This is always save, but may make the resulting run-time check
750   // bail out more often than strictly necessary.
751   Outside = Outside.remove_divs();
752   Outside = Outside.complement();
753   const auto &Loc = getAccessInstruction()
754                         ? getAccessInstruction()->getDebugLoc()
755                         : DebugLoc();
756   if (!PollyPreciseInbounds)
757     Outside = Outside.gist_params(Statement->getDomain().params());
758   Statement->getParent()->recordAssumption(INBOUNDS, Outside, Loc,
759                                            AS_ASSUMPTION);
760 }
761 
762 void MemoryAccess::buildMemIntrinsicAccessRelation() {
763   assert(isMemoryIntrinsic());
764   assert(Subscripts.size() == 2 && Sizes.size() == 1);
765 
766   isl::pw_aff SubscriptPWA = getPwAff(Subscripts[0]);
767   isl::map SubscriptMap = isl::map::from_pw_aff(SubscriptPWA);
768 
769   isl::map LengthMap;
770   if (Subscripts[1] == nullptr) {
771     LengthMap = isl::map::universe(SubscriptMap.get_space());
772   } else {
773     isl::pw_aff LengthPWA = getPwAff(Subscripts[1]);
774     LengthMap = isl::map::from_pw_aff(LengthPWA);
775     isl::space RangeSpace = LengthMap.get_space().range();
776     LengthMap = LengthMap.apply_range(isl::map::lex_gt(RangeSpace));
777   }
778   LengthMap = LengthMap.lower_bound_si(isl::dim::out, 0, 0);
779   LengthMap = LengthMap.align_params(SubscriptMap.get_space());
780   SubscriptMap = SubscriptMap.align_params(LengthMap.get_space());
781   LengthMap = LengthMap.sum(SubscriptMap);
782   AccessRelation =
783       LengthMap.set_tuple_id(isl::dim::in, getStatement()->getDomainId());
784 }
785 
786 void MemoryAccess::computeBoundsOnAccessRelation(unsigned ElementSize) {
787   ScalarEvolution *SE = Statement->getParent()->getSE();
788 
789   auto MAI = MemAccInst(getAccessInstruction());
790   if (isa<MemIntrinsic>(MAI))
791     return;
792 
793   Value *Ptr = MAI.getPointerOperand();
794   if (!Ptr || !SE->isSCEVable(Ptr->getType()))
795     return;
796 
797   auto *PtrSCEV = SE->getSCEV(Ptr);
798   if (isa<SCEVCouldNotCompute>(PtrSCEV))
799     return;
800 
801   auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
802   if (BasePtrSCEV && !isa<SCEVCouldNotCompute>(BasePtrSCEV))
803     PtrSCEV = SE->getMinusSCEV(PtrSCEV, BasePtrSCEV);
804 
805   const ConstantRange &Range = SE->getSignedRange(PtrSCEV);
806   if (Range.isFullSet())
807     return;
808 
809   if (Range.isUpperWrapped() || Range.isSignWrappedSet())
810     return;
811 
812   bool isWrapping = Range.isSignWrappedSet();
813 
814   unsigned BW = Range.getBitWidth();
815   const auto One = APInt(BW, 1);
816   const auto LB = isWrapping ? Range.getLower() : Range.getSignedMin();
817   const auto UB = isWrapping ? (Range.getUpper() - One) : Range.getSignedMax();
818 
819   auto Min = LB.sdiv(APInt(BW, ElementSize));
820   auto Max = UB.sdiv(APInt(BW, ElementSize)) + One;
821 
822   assert(Min.sle(Max) && "Minimum expected to be less or equal than max");
823 
824   isl::map Relation = AccessRelation;
825   isl::set AccessRange = Relation.range();
826   AccessRange = addRangeBoundsToSet(AccessRange, ConstantRange(Min, Max), 0,
827                                     isl::dim::set);
828   AccessRelation = Relation.intersect_range(AccessRange);
829 }
830 
831 void MemoryAccess::foldAccessRelation() {
832   if (Sizes.size() < 2 || isa<SCEVConstant>(Sizes[1]))
833     return;
834 
835   int Size = Subscripts.size();
836 
837   isl::map NewAccessRelation = AccessRelation;
838 
839   for (int i = Size - 2; i >= 0; --i) {
840     isl::space Space;
841     isl::map MapOne, MapTwo;
842     isl::pw_aff DimSize = getPwAff(Sizes[i + 1]);
843 
844     isl::space SpaceSize = DimSize.get_space();
845     isl::id ParamId = SpaceSize.get_dim_id(isl::dim::param, 0);
846 
847     Space = AccessRelation.get_space();
848     Space = Space.range().map_from_set();
849     Space = Space.align_params(SpaceSize);
850 
851     int ParamLocation = Space.find_dim_by_id(isl::dim::param, ParamId);
852 
853     MapOne = isl::map::universe(Space);
854     for (int j = 0; j < Size; ++j)
855       MapOne = MapOne.equate(isl::dim::in, j, isl::dim::out, j);
856     MapOne = MapOne.lower_bound_si(isl::dim::in, i + 1, 0);
857 
858     MapTwo = isl::map::universe(Space);
859     for (int j = 0; j < Size; ++j)
860       if (j < i || j > i + 1)
861         MapTwo = MapTwo.equate(isl::dim::in, j, isl::dim::out, j);
862 
863     isl::local_space LS(Space);
864     isl::constraint C;
865     C = isl::constraint::alloc_equality(LS);
866     C = C.set_constant_si(-1);
867     C = C.set_coefficient_si(isl::dim::in, i, 1);
868     C = C.set_coefficient_si(isl::dim::out, i, -1);
869     MapTwo = MapTwo.add_constraint(C);
870     C = isl::constraint::alloc_equality(LS);
871     C = C.set_coefficient_si(isl::dim::in, i + 1, 1);
872     C = C.set_coefficient_si(isl::dim::out, i + 1, -1);
873     C = C.set_coefficient_si(isl::dim::param, ParamLocation, 1);
874     MapTwo = MapTwo.add_constraint(C);
875     MapTwo = MapTwo.upper_bound_si(isl::dim::in, i + 1, -1);
876 
877     MapOne = MapOne.unite(MapTwo);
878     NewAccessRelation = NewAccessRelation.apply_range(MapOne);
879   }
880 
881   isl::id BaseAddrId = getScopArrayInfo()->getBasePtrId();
882   isl::space Space = Statement->getDomainSpace();
883   NewAccessRelation = NewAccessRelation.set_tuple_id(
884       isl::dim::in, Space.get_tuple_id(isl::dim::set));
885   NewAccessRelation = NewAccessRelation.set_tuple_id(isl::dim::out, BaseAddrId);
886   NewAccessRelation = NewAccessRelation.gist_domain(Statement->getDomain());
887 
888   // Access dimension folding might in certain cases increase the number of
889   // disjuncts in the memory access, which can possibly complicate the generated
890   // run-time checks and can lead to costly compilation.
891   if (!PollyPreciseFoldAccesses &&
892       NewAccessRelation.n_basic_map() > AccessRelation.n_basic_map()) {
893   } else {
894     AccessRelation = NewAccessRelation;
895   }
896 }
897 
898 /// Check if @p Expr is divisible by @p Size.
899 static bool isDivisible(const SCEV *Expr, unsigned Size, ScalarEvolution &SE) {
900   assert(Size != 0);
901   if (Size == 1)
902     return true;
903 
904   // Only one factor needs to be divisible.
905   if (auto *MulExpr = dyn_cast<SCEVMulExpr>(Expr)) {
906     for (auto *FactorExpr : MulExpr->operands())
907       if (isDivisible(FactorExpr, Size, SE))
908         return true;
909     return false;
910   }
911 
912   // For other n-ary expressions (Add, AddRec, Max,...) all operands need
913   // to be divisible.
914   if (auto *NAryExpr = dyn_cast<SCEVNAryExpr>(Expr)) {
915     for (auto *OpExpr : NAryExpr->operands())
916       if (!isDivisible(OpExpr, Size, SE))
917         return false;
918     return true;
919   }
920 
921   auto *SizeSCEV = SE.getConstant(Expr->getType(), Size);
922   auto *UDivSCEV = SE.getUDivExpr(Expr, SizeSCEV);
923   auto *MulSCEV = SE.getMulExpr(UDivSCEV, SizeSCEV);
924   return MulSCEV == Expr;
925 }
926 
927 void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) {
928   assert(AccessRelation.is_null() && "AccessRelation already built");
929 
930   // Initialize the invalid domain which describes all iterations for which the
931   // access relation is not modeled correctly.
932   isl::set StmtInvalidDomain = getStatement()->getInvalidDomain();
933   InvalidDomain = isl::set::empty(StmtInvalidDomain.get_space());
934 
935   isl::ctx Ctx = Id.get_ctx();
936   isl::id BaseAddrId = SAI->getBasePtrId();
937 
938   if (getAccessInstruction() && isa<MemIntrinsic>(getAccessInstruction())) {
939     buildMemIntrinsicAccessRelation();
940     AccessRelation = AccessRelation.set_tuple_id(isl::dim::out, BaseAddrId);
941     return;
942   }
943 
944   if (!isAffine()) {
945     // We overapproximate non-affine accesses with a possible access to the
946     // whole array. For read accesses it does not make a difference, if an
947     // access must or may happen. However, for write accesses it is important to
948     // differentiate between writes that must happen and writes that may happen.
949     if (AccessRelation.is_null())
950       AccessRelation = createBasicAccessMap(Statement);
951 
952     AccessRelation = AccessRelation.set_tuple_id(isl::dim::out, BaseAddrId);
953     return;
954   }
955 
956   isl::space Space = isl::space(Ctx, 0, Statement->getNumIterators(), 0);
957   AccessRelation = isl::map::universe(Space);
958 
959   for (int i = 0, Size = Subscripts.size(); i < Size; ++i) {
960     isl::pw_aff Affine = getPwAff(Subscripts[i]);
961     isl::map SubscriptMap = isl::map::from_pw_aff(Affine);
962     AccessRelation = AccessRelation.flat_range_product(SubscriptMap);
963   }
964 
965   Space = Statement->getDomainSpace();
966   AccessRelation = AccessRelation.set_tuple_id(
967       isl::dim::in, Space.get_tuple_id(isl::dim::set));
968   AccessRelation = AccessRelation.set_tuple_id(isl::dim::out, BaseAddrId);
969 
970   AccessRelation = AccessRelation.gist_domain(Statement->getDomain());
971 }
972 
973 MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
974                            AccessType AccType, Value *BaseAddress,
975                            Type *ElementType, bool Affine,
976                            ArrayRef<const SCEV *> Subscripts,
977                            ArrayRef<const SCEV *> Sizes, Value *AccessValue,
978                            MemoryKind Kind)
979     : Kind(Kind), AccType(AccType), Statement(Stmt), InvalidDomain(nullptr),
980       BaseAddr(BaseAddress), ElementType(ElementType),
981       Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst),
982       AccessValue(AccessValue), IsAffine(Affine),
983       Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(nullptr),
984       NewAccessRelation(nullptr), FAD(nullptr) {
985   static const std::string TypeStrings[] = {"", "_Read", "_Write", "_MayWrite"};
986   const std::string Access = TypeStrings[AccType] + utostr(Stmt->size());
987 
988   std::string IdName = Stmt->getBaseName() + Access;
989   Id = isl::id::alloc(Stmt->getParent()->getIslCtx(), IdName, this);
990 }
991 
992 MemoryAccess::MemoryAccess(ScopStmt *Stmt, AccessType AccType, isl::map AccRel)
993     : Kind(MemoryKind::Array), AccType(AccType), Statement(Stmt),
994       InvalidDomain(nullptr), AccessRelation(nullptr),
995       NewAccessRelation(AccRel), FAD(nullptr) {
996   isl::id ArrayInfoId = NewAccessRelation.get_tuple_id(isl::dim::out);
997   auto *SAI = ScopArrayInfo::getFromId(ArrayInfoId);
998   Sizes.push_back(nullptr);
999   for (unsigned i = 1; i < SAI->getNumberOfDimensions(); i++)
1000     Sizes.push_back(SAI->getDimensionSize(i));
1001   ElementType = SAI->getElementType();
1002   BaseAddr = SAI->getBasePtr();
1003   static const std::string TypeStrings[] = {"", "_Read", "_Write", "_MayWrite"};
1004   const std::string Access = TypeStrings[AccType] + utostr(Stmt->size());
1005 
1006   std::string IdName = Stmt->getBaseName() + Access;
1007   Id = isl::id::alloc(Stmt->getParent()->getIslCtx(), IdName, this);
1008 }
1009 
1010 MemoryAccess::~MemoryAccess() = default;
1011 
1012 void MemoryAccess::realignParams() {
1013   isl::set Ctx = Statement->getParent()->getContext();
1014   InvalidDomain = InvalidDomain.gist_params(Ctx);
1015   AccessRelation = AccessRelation.gist_params(Ctx);
1016 }
1017 
1018 const std::string MemoryAccess::getReductionOperatorStr() const {
1019   return MemoryAccess::getReductionOperatorStr(getReductionType());
1020 }
1021 
1022 isl::id MemoryAccess::getId() const { return Id; }
1023 
1024 raw_ostream &polly::operator<<(raw_ostream &OS,
1025                                MemoryAccess::ReductionType RT) {
1026   if (RT == MemoryAccess::RT_NONE)
1027     OS << "NONE";
1028   else
1029     OS << MemoryAccess::getReductionOperatorStr(RT);
1030   return OS;
1031 }
1032 
1033 void MemoryAccess::setFortranArrayDescriptor(Value *FAD) { this->FAD = FAD; }
1034 
1035 void MemoryAccess::print(raw_ostream &OS) const {
1036   switch (AccType) {
1037   case READ:
1038     OS.indent(12) << "ReadAccess :=\t";
1039     break;
1040   case MUST_WRITE:
1041     OS.indent(12) << "MustWriteAccess :=\t";
1042     break;
1043   case MAY_WRITE:
1044     OS.indent(12) << "MayWriteAccess :=\t";
1045     break;
1046   }
1047 
1048   OS << "[Reduction Type: " << getReductionType() << "] ";
1049 
1050   if (FAD) {
1051     OS << "[Fortran array descriptor: " << FAD->getName();
1052     OS << "] ";
1053   };
1054 
1055   OS << "[Scalar: " << isScalarKind() << "]\n";
1056   OS.indent(16) << getOriginalAccessRelationStr() << ";\n";
1057   if (hasNewAccessRelation())
1058     OS.indent(11) << "new: " << getNewAccessRelationStr() << ";\n";
1059 }
1060 
1061 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1062 LLVM_DUMP_METHOD void MemoryAccess::dump() const { print(errs()); }
1063 #endif
1064 
1065 isl::pw_aff MemoryAccess::getPwAff(const SCEV *E) {
1066   auto *Stmt = getStatement();
1067   PWACtx PWAC = Stmt->getParent()->getPwAff(E, Stmt->getEntryBlock());
1068   isl::set StmtDom = getStatement()->getDomain();
1069   StmtDom = StmtDom.reset_tuple_id();
1070   isl::set NewInvalidDom = StmtDom.intersect(PWAC.second);
1071   InvalidDomain = InvalidDomain.unite(NewInvalidDom);
1072   return PWAC.first;
1073 }
1074 
1075 // Create a map in the size of the provided set domain, that maps from the
1076 // one element of the provided set domain to another element of the provided
1077 // set domain.
1078 // The mapping is limited to all points that are equal in all but the last
1079 // dimension and for which the last dimension of the input is strict smaller
1080 // than the last dimension of the output.
1081 //
1082 //   getEqualAndLarger(set[i0, i1, ..., iX]):
1083 //
1084 //   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
1085 //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
1086 //
1087 static isl::map getEqualAndLarger(isl::space SetDomain) {
1088   isl::space Space = SetDomain.map_from_set();
1089   isl::map Map = isl::map::universe(Space);
1090   unsigned lastDimension = Map.dim(isl::dim::in) - 1;
1091 
1092   // Set all but the last dimension to be equal for the input and output
1093   //
1094   //   input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
1095   //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
1096   for (unsigned i = 0; i < lastDimension; ++i)
1097     Map = Map.equate(isl::dim::in, i, isl::dim::out, i);
1098 
1099   // Set the last dimension of the input to be strict smaller than the
1100   // last dimension of the output.
1101   //
1102   //   input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
1103   Map = Map.order_lt(isl::dim::in, lastDimension, isl::dim::out, lastDimension);
1104   return Map;
1105 }
1106 
1107 isl::set MemoryAccess::getStride(isl::map Schedule) const {
1108   isl::map AccessRelation = getAccessRelation();
1109   isl::space Space = Schedule.get_space().range();
1110   isl::map NextScatt = getEqualAndLarger(Space);
1111 
1112   Schedule = Schedule.reverse();
1113   NextScatt = NextScatt.lexmin();
1114 
1115   NextScatt = NextScatt.apply_range(Schedule);
1116   NextScatt = NextScatt.apply_range(AccessRelation);
1117   NextScatt = NextScatt.apply_domain(Schedule);
1118   NextScatt = NextScatt.apply_domain(AccessRelation);
1119 
1120   isl::set Deltas = NextScatt.deltas();
1121   return Deltas;
1122 }
1123 
1124 bool MemoryAccess::isStrideX(isl::map Schedule, int StrideWidth) const {
1125   isl::set Stride, StrideX;
1126   bool IsStrideX;
1127 
1128   Stride = getStride(Schedule);
1129   StrideX = isl::set::universe(Stride.get_space());
1130   for (unsigned i = 0; i < StrideX.dim(isl::dim::set) - 1; i++)
1131     StrideX = StrideX.fix_si(isl::dim::set, i, 0);
1132   StrideX = StrideX.fix_si(isl::dim::set, StrideX.dim(isl::dim::set) - 1,
1133                            StrideWidth);
1134   IsStrideX = Stride.is_subset(StrideX);
1135 
1136   return IsStrideX;
1137 }
1138 
1139 bool MemoryAccess::isStrideZero(isl::map Schedule) const {
1140   return isStrideX(Schedule, 0);
1141 }
1142 
1143 bool MemoryAccess::isStrideOne(isl::map Schedule) const {
1144   return isStrideX(Schedule, 1);
1145 }
1146 
1147 void MemoryAccess::setAccessRelation(isl::map NewAccess) {
1148   AccessRelation = NewAccess;
1149 }
1150 
1151 void MemoryAccess::setNewAccessRelation(isl::map NewAccess) {
1152   assert(NewAccess);
1153 
1154 #ifndef NDEBUG
1155   // Check domain space compatibility.
1156   isl::space NewSpace = NewAccess.get_space();
1157   isl::space NewDomainSpace = NewSpace.domain();
1158   isl::space OriginalDomainSpace = getStatement()->getDomainSpace();
1159   assert(OriginalDomainSpace.has_equal_tuples(NewDomainSpace));
1160 
1161   // Reads must be executed unconditionally. Writes might be executed in a
1162   // subdomain only.
1163   if (isRead()) {
1164     // Check whether there is an access for every statement instance.
1165     isl::set StmtDomain = getStatement()->getDomain();
1166     StmtDomain =
1167         StmtDomain.intersect_params(getStatement()->getParent()->getContext());
1168     isl::set NewDomain = NewAccess.domain();
1169     assert(StmtDomain.is_subset(NewDomain) &&
1170            "Partial READ accesses not supported");
1171   }
1172 
1173   isl::space NewAccessSpace = NewAccess.get_space();
1174   assert(NewAccessSpace.has_tuple_id(isl::dim::set) &&
1175          "Must specify the array that is accessed");
1176   isl::id NewArrayId = NewAccessSpace.get_tuple_id(isl::dim::set);
1177   auto *SAI = static_cast<ScopArrayInfo *>(NewArrayId.get_user());
1178   assert(SAI && "Must set a ScopArrayInfo");
1179 
1180   if (SAI->isArrayKind() && SAI->getBasePtrOriginSAI()) {
1181     InvariantEquivClassTy *EqClass =
1182         getStatement()->getParent()->lookupInvariantEquivClass(
1183             SAI->getBasePtr());
1184     assert(EqClass &&
1185            "Access functions to indirect arrays must have an invariant and "
1186            "hoisted base pointer");
1187   }
1188 
1189   // Check whether access dimensions correspond to number of dimensions of the
1190   // accesses array.
1191   auto Dims = SAI->getNumberOfDimensions();
1192   assert(NewAccessSpace.dim(isl::dim::set) == Dims &&
1193          "Access dims must match array dims");
1194 #endif
1195 
1196   NewAccess = NewAccess.gist_domain(getStatement()->getDomain());
1197   NewAccessRelation = NewAccess;
1198 }
1199 
1200 bool MemoryAccess::isLatestPartialAccess() const {
1201   isl::set StmtDom = getStatement()->getDomain();
1202   isl::set AccDom = getLatestAccessRelation().domain();
1203 
1204   return !StmtDom.is_subset(AccDom);
1205 }
1206 
1207 //===----------------------------------------------------------------------===//
1208 
1209 isl::map ScopStmt::getSchedule() const {
1210   isl::set Domain = getDomain();
1211   if (Domain.is_empty())
1212     return isl::map::from_aff(isl::aff(isl::local_space(getDomainSpace())));
1213   auto Schedule = getParent()->getSchedule();
1214   if (!Schedule)
1215     return nullptr;
1216   Schedule = Schedule.intersect_domain(isl::union_set(Domain));
1217   if (Schedule.is_empty())
1218     return isl::map::from_aff(isl::aff(isl::local_space(getDomainSpace())));
1219   isl::map M = M.from_union_map(Schedule);
1220   M = M.coalesce();
1221   M = M.gist_domain(Domain);
1222   M = M.coalesce();
1223   return M;
1224 }
1225 
1226 void ScopStmt::restrictDomain(isl::set NewDomain) {
1227   assert(NewDomain.is_subset(Domain) &&
1228          "New domain is not a subset of old domain!");
1229   Domain = NewDomain;
1230 }
1231 
1232 void ScopStmt::addAccess(MemoryAccess *Access, bool Prepend) {
1233   Instruction *AccessInst = Access->getAccessInstruction();
1234 
1235   if (Access->isArrayKind()) {
1236     MemoryAccessList &MAL = InstructionToAccess[AccessInst];
1237     MAL.emplace_front(Access);
1238   } else if (Access->isValueKind() && Access->isWrite()) {
1239     Instruction *AccessVal = cast<Instruction>(Access->getAccessValue());
1240     assert(!ValueWrites.lookup(AccessVal));
1241 
1242     ValueWrites[AccessVal] = Access;
1243   } else if (Access->isValueKind() && Access->isRead()) {
1244     Value *AccessVal = Access->getAccessValue();
1245     assert(!ValueReads.lookup(AccessVal));
1246 
1247     ValueReads[AccessVal] = Access;
1248   } else if (Access->isAnyPHIKind() && Access->isWrite()) {
1249     PHINode *PHI = cast<PHINode>(Access->getAccessValue());
1250     assert(!PHIWrites.lookup(PHI));
1251 
1252     PHIWrites[PHI] = Access;
1253   } else if (Access->isAnyPHIKind() && Access->isRead()) {
1254     PHINode *PHI = cast<PHINode>(Access->getAccessValue());
1255     assert(!PHIReads.lookup(PHI));
1256 
1257     PHIReads[PHI] = Access;
1258   }
1259 
1260   if (Prepend) {
1261     MemAccs.insert(MemAccs.begin(), Access);
1262     return;
1263   }
1264   MemAccs.push_back(Access);
1265 }
1266 
1267 void ScopStmt::realignParams() {
1268   for (MemoryAccess *MA : *this)
1269     MA->realignParams();
1270 
1271   isl::set Ctx = Parent.getContext();
1272   InvalidDomain = InvalidDomain.gist_params(Ctx);
1273   Domain = Domain.gist_params(Ctx);
1274 }
1275 
1276 /// Add @p BSet to set @p BoundedParts if @p BSet is bounded.
1277 static isl::set collectBoundedParts(isl::set S) {
1278   isl::set BoundedParts = isl::set::empty(S.get_space());
1279   for (isl::basic_set BSet : S.get_basic_set_list())
1280     if (BSet.is_bounded())
1281       BoundedParts = BoundedParts.unite(isl::set(BSet));
1282   return BoundedParts;
1283 }
1284 
1285 /// Compute the (un)bounded parts of @p S wrt. to dimension @p Dim.
1286 ///
1287 /// @returns A separation of @p S into first an unbounded then a bounded subset,
1288 ///          both with regards to the dimension @p Dim.
1289 static std::pair<isl::set, isl::set> partitionSetParts(isl::set S,
1290                                                        unsigned Dim) {
1291   for (unsigned u = 0, e = S.n_dim(); u < e; u++)
1292     S = S.lower_bound_si(isl::dim::set, u, 0);
1293 
1294   unsigned NumDimsS = S.n_dim();
1295   isl::set OnlyDimS = S;
1296 
1297   // Remove dimensions that are greater than Dim as they are not interesting.
1298   assert(NumDimsS >= Dim + 1);
1299   OnlyDimS = OnlyDimS.project_out(isl::dim::set, Dim + 1, NumDimsS - Dim - 1);
1300 
1301   // Create artificial parametric upper bounds for dimensions smaller than Dim
1302   // as we are not interested in them.
1303   OnlyDimS = OnlyDimS.insert_dims(isl::dim::param, 0, Dim);
1304 
1305   for (unsigned u = 0; u < Dim; u++) {
1306     isl::constraint C = isl::constraint::alloc_inequality(
1307         isl::local_space(OnlyDimS.get_space()));
1308     C = C.set_coefficient_si(isl::dim::param, u, 1);
1309     C = C.set_coefficient_si(isl::dim::set, u, -1);
1310     OnlyDimS = OnlyDimS.add_constraint(C);
1311   }
1312 
1313   // Collect all bounded parts of OnlyDimS.
1314   isl::set BoundedParts = collectBoundedParts(OnlyDimS);
1315 
1316   // Create the dimensions greater than Dim again.
1317   BoundedParts =
1318       BoundedParts.insert_dims(isl::dim::set, Dim + 1, NumDimsS - Dim - 1);
1319 
1320   // Remove the artificial upper bound parameters again.
1321   BoundedParts = BoundedParts.remove_dims(isl::dim::param, 0, Dim);
1322 
1323   isl::set UnboundedParts = S.subtract(BoundedParts);
1324   return std::make_pair(UnboundedParts, BoundedParts);
1325 }
1326 
1327 /// Create the conditions under which @p L @p Pred @p R is true.
1328 static isl::set buildConditionSet(ICmpInst::Predicate Pred, isl::pw_aff L,
1329                                   isl::pw_aff R) {
1330   switch (Pred) {
1331   case ICmpInst::ICMP_EQ:
1332     return L.eq_set(R);
1333   case ICmpInst::ICMP_NE:
1334     return L.ne_set(R);
1335   case ICmpInst::ICMP_SLT:
1336     return L.lt_set(R);
1337   case ICmpInst::ICMP_SLE:
1338     return L.le_set(R);
1339   case ICmpInst::ICMP_SGT:
1340     return L.gt_set(R);
1341   case ICmpInst::ICMP_SGE:
1342     return L.ge_set(R);
1343   case ICmpInst::ICMP_ULT:
1344     return L.lt_set(R);
1345   case ICmpInst::ICMP_UGT:
1346     return L.gt_set(R);
1347   case ICmpInst::ICMP_ULE:
1348     return L.le_set(R);
1349   case ICmpInst::ICMP_UGE:
1350     return L.ge_set(R);
1351   default:
1352     llvm_unreachable("Non integer predicate not supported");
1353   }
1354 }
1355 
1356 /// Compute the isl representation for the SCEV @p E in this BB.
1357 ///
1358 /// @param S                The Scop in which @p BB resides in.
1359 /// @param BB               The BB for which isl representation is to be
1360 /// computed.
1361 /// @param InvalidDomainMap A map of BB to their invalid domains.
1362 /// @param E                The SCEV that should be translated.
1363 /// @param NonNegative      Flag to indicate the @p E has to be non-negative.
1364 ///
1365 /// Note that this function will also adjust the invalid context accordingly.
1366 
1367 __isl_give isl_pw_aff *
1368 getPwAff(Scop &S, BasicBlock *BB,
1369          DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, const SCEV *E,
1370          bool NonNegative = false) {
1371   PWACtx PWAC = S.getPwAff(E, BB, NonNegative);
1372   InvalidDomainMap[BB] = InvalidDomainMap[BB].unite(PWAC.second);
1373   return PWAC.first.release();
1374 }
1375 
1376 /// Build the conditions sets for the switch @p SI in the @p Domain.
1377 ///
1378 /// This will fill @p ConditionSets with the conditions under which control
1379 /// will be moved from @p SI to its successors. Hence, @p ConditionSets will
1380 /// have as many elements as @p SI has successors.
1381 bool buildConditionSets(Scop &S, BasicBlock *BB, SwitchInst *SI, Loop *L,
1382                         __isl_keep isl_set *Domain,
1383                         DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
1384                         SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
1385   Value *Condition = getConditionFromTerminator(SI);
1386   assert(Condition && "No condition for switch");
1387 
1388   ScalarEvolution &SE = *S.getSE();
1389   isl_pw_aff *LHS, *RHS;
1390   LHS = getPwAff(S, BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L));
1391 
1392   unsigned NumSuccessors = SI->getNumSuccessors();
1393   ConditionSets.resize(NumSuccessors);
1394   for (auto &Case : SI->cases()) {
1395     unsigned Idx = Case.getSuccessorIndex();
1396     ConstantInt *CaseValue = Case.getCaseValue();
1397 
1398     RHS = getPwAff(S, BB, InvalidDomainMap, SE.getSCEV(CaseValue));
1399     isl_set *CaseConditionSet =
1400         buildConditionSet(ICmpInst::ICMP_EQ, isl::manage_copy(LHS),
1401                           isl::manage(RHS))
1402             .release();
1403     ConditionSets[Idx] = isl_set_coalesce(
1404         isl_set_intersect(CaseConditionSet, isl_set_copy(Domain)));
1405   }
1406 
1407   assert(ConditionSets[0] == nullptr && "Default condition set was set");
1408   isl_set *ConditionSetUnion = isl_set_copy(ConditionSets[1]);
1409   for (unsigned u = 2; u < NumSuccessors; u++)
1410     ConditionSetUnion =
1411         isl_set_union(ConditionSetUnion, isl_set_copy(ConditionSets[u]));
1412   ConditionSets[0] = isl_set_subtract(isl_set_copy(Domain), ConditionSetUnion);
1413 
1414   isl_pw_aff_free(LHS);
1415 
1416   return true;
1417 }
1418 
1419 /// Build condition sets for unsigned ICmpInst(s).
1420 /// Special handling is required for unsigned operands to ensure that if
1421 /// MSB (aka the Sign bit) is set for an operands in an unsigned ICmpInst
1422 /// it should wrap around.
1423 ///
1424 /// @param IsStrictUpperBound holds information on the predicate relation
1425 /// between TestVal and UpperBound, i.e,
1426 /// TestVal < UpperBound  OR  TestVal <= UpperBound
1427 __isl_give isl_set *
1428 buildUnsignedConditionSets(Scop &S, BasicBlock *BB, Value *Condition,
1429                            __isl_keep isl_set *Domain, const SCEV *SCEV_TestVal,
1430                            const SCEV *SCEV_UpperBound,
1431                            DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
1432                            bool IsStrictUpperBound) {
1433   // Do not take NonNeg assumption on TestVal
1434   // as it might have MSB (Sign bit) set.
1435   isl_pw_aff *TestVal = getPwAff(S, BB, InvalidDomainMap, SCEV_TestVal, false);
1436   // Take NonNeg assumption on UpperBound.
1437   isl_pw_aff *UpperBound =
1438       getPwAff(S, BB, InvalidDomainMap, SCEV_UpperBound, true);
1439 
1440   // 0 <= TestVal
1441   isl_set *First =
1442       isl_pw_aff_le_set(isl_pw_aff_zero_on_domain(isl_local_space_from_space(
1443                             isl_pw_aff_get_domain_space(TestVal))),
1444                         isl_pw_aff_copy(TestVal));
1445 
1446   isl_set *Second;
1447   if (IsStrictUpperBound)
1448     // TestVal < UpperBound
1449     Second = isl_pw_aff_lt_set(TestVal, UpperBound);
1450   else
1451     // TestVal <= UpperBound
1452     Second = isl_pw_aff_le_set(TestVal, UpperBound);
1453 
1454   isl_set *ConsequenceCondSet = isl_set_intersect(First, Second);
1455   return ConsequenceCondSet;
1456 }
1457 
1458 /// Build the conditions sets for the branch condition @p Condition in
1459 /// the @p Domain.
1460 ///
1461 /// This will fill @p ConditionSets with the conditions under which control
1462 /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
1463 /// have as many elements as @p TI has successors. If @p TI is nullptr the
1464 /// context under which @p Condition is true/false will be returned as the
1465 /// new elements of @p ConditionSets.
1466 bool buildConditionSets(Scop &S, BasicBlock *BB, Value *Condition,
1467                         Instruction *TI, Loop *L, __isl_keep isl_set *Domain,
1468                         DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
1469                         SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
1470   ScalarEvolution &SE = *S.getSE();
1471   isl_set *ConsequenceCondSet = nullptr;
1472 
1473   if (auto Load = dyn_cast<LoadInst>(Condition)) {
1474     const SCEV *LHSSCEV = SE.getSCEVAtScope(Load, L);
1475     const SCEV *RHSSCEV = SE.getZero(LHSSCEV->getType());
1476     bool NonNeg = false;
1477     isl_pw_aff *LHS = getPwAff(S, BB, InvalidDomainMap, LHSSCEV, NonNeg);
1478     isl_pw_aff *RHS = getPwAff(S, BB, InvalidDomainMap, RHSSCEV, NonNeg);
1479     ConsequenceCondSet = buildConditionSet(ICmpInst::ICMP_SLE, isl::manage(LHS),
1480                                            isl::manage(RHS))
1481                              .release();
1482   } else if (auto *PHI = dyn_cast<PHINode>(Condition)) {
1483     auto *Unique = dyn_cast<ConstantInt>(
1484         getUniqueNonErrorValue(PHI, &S.getRegion(), *S.getLI(), *S.getDT()));
1485 
1486     if (Unique->isZero())
1487       ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain));
1488     else
1489       ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain));
1490   } else if (auto *CCond = dyn_cast<ConstantInt>(Condition)) {
1491     if (CCond->isZero())
1492       ConsequenceCondSet = isl_set_empty(isl_set_get_space(Domain));
1493     else
1494       ConsequenceCondSet = isl_set_universe(isl_set_get_space(Domain));
1495   } else if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Condition)) {
1496     auto Opcode = BinOp->getOpcode();
1497     assert(Opcode == Instruction::And || Opcode == Instruction::Or);
1498 
1499     bool Valid = buildConditionSets(S, BB, BinOp->getOperand(0), TI, L, Domain,
1500                                     InvalidDomainMap, ConditionSets) &&
1501                  buildConditionSets(S, BB, BinOp->getOperand(1), TI, L, Domain,
1502                                     InvalidDomainMap, ConditionSets);
1503     if (!Valid) {
1504       while (!ConditionSets.empty())
1505         isl_set_free(ConditionSets.pop_back_val());
1506       return false;
1507     }
1508 
1509     isl_set_free(ConditionSets.pop_back_val());
1510     isl_set *ConsCondPart0 = ConditionSets.pop_back_val();
1511     isl_set_free(ConditionSets.pop_back_val());
1512     isl_set *ConsCondPart1 = ConditionSets.pop_back_val();
1513 
1514     if (Opcode == Instruction::And)
1515       ConsequenceCondSet = isl_set_intersect(ConsCondPart0, ConsCondPart1);
1516     else
1517       ConsequenceCondSet = isl_set_union(ConsCondPart0, ConsCondPart1);
1518   } else {
1519     auto *ICond = dyn_cast<ICmpInst>(Condition);
1520     assert(ICond &&
1521            "Condition of exiting branch was neither constant nor ICmp!");
1522 
1523     LoopInfo &LI = *S.getLI();
1524     DominatorTree &DT = *S.getDT();
1525     Region &R = S.getRegion();
1526 
1527     isl_pw_aff *LHS, *RHS;
1528     // For unsigned comparisons we assumed the signed bit of neither operand
1529     // to be set. The comparison is equal to a signed comparison under this
1530     // assumption.
1531     bool NonNeg = ICond->isUnsigned();
1532     const SCEV *LeftOperand = SE.getSCEVAtScope(ICond->getOperand(0), L),
1533                *RightOperand = SE.getSCEVAtScope(ICond->getOperand(1), L);
1534 
1535     LeftOperand = tryForwardThroughPHI(LeftOperand, R, SE, LI, DT);
1536     RightOperand = tryForwardThroughPHI(RightOperand, R, SE, LI, DT);
1537 
1538     switch (ICond->getPredicate()) {
1539     case ICmpInst::ICMP_ULT:
1540       ConsequenceCondSet =
1541           buildUnsignedConditionSets(S, BB, Condition, Domain, LeftOperand,
1542                                      RightOperand, InvalidDomainMap, true);
1543       break;
1544     case ICmpInst::ICMP_ULE:
1545       ConsequenceCondSet =
1546           buildUnsignedConditionSets(S, BB, Condition, Domain, LeftOperand,
1547                                      RightOperand, InvalidDomainMap, false);
1548       break;
1549     case ICmpInst::ICMP_UGT:
1550       ConsequenceCondSet =
1551           buildUnsignedConditionSets(S, BB, Condition, Domain, RightOperand,
1552                                      LeftOperand, InvalidDomainMap, true);
1553       break;
1554     case ICmpInst::ICMP_UGE:
1555       ConsequenceCondSet =
1556           buildUnsignedConditionSets(S, BB, Condition, Domain, RightOperand,
1557                                      LeftOperand, InvalidDomainMap, false);
1558       break;
1559     default:
1560       LHS = getPwAff(S, BB, InvalidDomainMap, LeftOperand, NonNeg);
1561       RHS = getPwAff(S, BB, InvalidDomainMap, RightOperand, NonNeg);
1562       ConsequenceCondSet = buildConditionSet(ICond->getPredicate(),
1563                                              isl::manage(LHS), isl::manage(RHS))
1564                                .release();
1565       break;
1566     }
1567   }
1568 
1569   // If no terminator was given we are only looking for parameter constraints
1570   // under which @p Condition is true/false.
1571   if (!TI)
1572     ConsequenceCondSet = isl_set_params(ConsequenceCondSet);
1573   assert(ConsequenceCondSet);
1574   ConsequenceCondSet = isl_set_coalesce(
1575       isl_set_intersect(ConsequenceCondSet, isl_set_copy(Domain)));
1576 
1577   isl_set *AlternativeCondSet = nullptr;
1578   bool TooComplex =
1579       isl_set_n_basic_set(ConsequenceCondSet) >= MaxDisjunctsInDomain;
1580 
1581   if (!TooComplex) {
1582     AlternativeCondSet = isl_set_subtract(isl_set_copy(Domain),
1583                                           isl_set_copy(ConsequenceCondSet));
1584     TooComplex =
1585         isl_set_n_basic_set(AlternativeCondSet) >= MaxDisjunctsInDomain;
1586   }
1587 
1588   if (TooComplex) {
1589     S.invalidate(COMPLEXITY, TI ? TI->getDebugLoc() : DebugLoc(),
1590                  TI ? TI->getParent() : nullptr /* BasicBlock */);
1591     isl_set_free(AlternativeCondSet);
1592     isl_set_free(ConsequenceCondSet);
1593     return false;
1594   }
1595 
1596   ConditionSets.push_back(ConsequenceCondSet);
1597   ConditionSets.push_back(isl_set_coalesce(AlternativeCondSet));
1598 
1599   return true;
1600 }
1601 
1602 /// Build the conditions sets for the terminator @p TI in the @p Domain.
1603 ///
1604 /// This will fill @p ConditionSets with the conditions under which control
1605 /// will be moved from @p TI to its successors. Hence, @p ConditionSets will
1606 /// have as many elements as @p TI has successors.
1607 bool buildConditionSets(Scop &S, BasicBlock *BB, Instruction *TI, Loop *L,
1608                         __isl_keep isl_set *Domain,
1609                         DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
1610                         SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
1611   if (SwitchInst *SI = dyn_cast<SwitchInst>(TI))
1612     return buildConditionSets(S, BB, SI, L, Domain, InvalidDomainMap,
1613                               ConditionSets);
1614 
1615   assert(isa<BranchInst>(TI) && "Terminator was neither branch nor switch.");
1616 
1617   if (TI->getNumSuccessors() == 1) {
1618     ConditionSets.push_back(isl_set_copy(Domain));
1619     return true;
1620   }
1621 
1622   Value *Condition = getConditionFromTerminator(TI);
1623   assert(Condition && "No condition for Terminator");
1624 
1625   return buildConditionSets(S, BB, Condition, TI, L, Domain, InvalidDomainMap,
1626                             ConditionSets);
1627 }
1628 
1629 ScopStmt::ScopStmt(Scop &parent, Region &R, StringRef Name,
1630                    Loop *SurroundingLoop,
1631                    std::vector<Instruction *> EntryBlockInstructions)
1632     : Parent(parent), InvalidDomain(nullptr), Domain(nullptr), R(&R),
1633       Build(nullptr), BaseName(Name), SurroundingLoop(SurroundingLoop),
1634       Instructions(EntryBlockInstructions) {}
1635 
1636 ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb, StringRef Name,
1637                    Loop *SurroundingLoop,
1638                    std::vector<Instruction *> Instructions)
1639     : Parent(parent), InvalidDomain(nullptr), Domain(nullptr), BB(&bb),
1640       Build(nullptr), BaseName(Name), SurroundingLoop(SurroundingLoop),
1641       Instructions(Instructions) {}
1642 
1643 ScopStmt::ScopStmt(Scop &parent, isl::map SourceRel, isl::map TargetRel,
1644                    isl::set NewDomain)
1645     : Parent(parent), InvalidDomain(nullptr), Domain(NewDomain),
1646       Build(nullptr) {
1647   BaseName = getIslCompatibleName("CopyStmt_", "",
1648                                   std::to_string(parent.getCopyStmtsNum()));
1649   isl::id Id = isl::id::alloc(getIslCtx(), getBaseName(), this);
1650   Domain = Domain.set_tuple_id(Id);
1651   TargetRel = TargetRel.set_tuple_id(isl::dim::in, Id);
1652   auto *Access =
1653       new MemoryAccess(this, MemoryAccess::AccessType::MUST_WRITE, TargetRel);
1654   parent.addAccessFunction(Access);
1655   addAccess(Access);
1656   SourceRel = SourceRel.set_tuple_id(isl::dim::in, Id);
1657   Access = new MemoryAccess(this, MemoryAccess::AccessType::READ, SourceRel);
1658   parent.addAccessFunction(Access);
1659   addAccess(Access);
1660 }
1661 
1662 ScopStmt::~ScopStmt() = default;
1663 
1664 std::string ScopStmt::getDomainStr() const { return Domain.to_str(); }
1665 
1666 std::string ScopStmt::getScheduleStr() const {
1667   auto *S = getSchedule().release();
1668   if (!S)
1669     return {};
1670   auto Str = stringFromIslObj(S);
1671   isl_map_free(S);
1672   return Str;
1673 }
1674 
1675 void ScopStmt::setInvalidDomain(isl::set ID) { InvalidDomain = ID; }
1676 
1677 BasicBlock *ScopStmt::getEntryBlock() const {
1678   if (isBlockStmt())
1679     return getBasicBlock();
1680   return getRegion()->getEntry();
1681 }
1682 
1683 unsigned ScopStmt::getNumIterators() const { return NestLoops.size(); }
1684 
1685 const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
1686 
1687 Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
1688   return NestLoops[Dimension];
1689 }
1690 
1691 isl::ctx ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
1692 
1693 isl::set ScopStmt::getDomain() const { return Domain; }
1694 
1695 isl::space ScopStmt::getDomainSpace() const { return Domain.get_space(); }
1696 
1697 isl::id ScopStmt::getDomainId() const { return Domain.get_tuple_id(); }
1698 
1699 void ScopStmt::printInstructions(raw_ostream &OS) const {
1700   OS << "Instructions {\n";
1701 
1702   for (Instruction *Inst : Instructions)
1703     OS.indent(16) << *Inst << "\n";
1704 
1705   OS.indent(12) << "}\n";
1706 }
1707 
1708 void ScopStmt::print(raw_ostream &OS, bool PrintInstructions) const {
1709   OS << "\t" << getBaseName() << "\n";
1710   OS.indent(12) << "Domain :=\n";
1711 
1712   if (Domain) {
1713     OS.indent(16) << getDomainStr() << ";\n";
1714   } else
1715     OS.indent(16) << "n/a\n";
1716 
1717   OS.indent(12) << "Schedule :=\n";
1718 
1719   if (Domain) {
1720     OS.indent(16) << getScheduleStr() << ";\n";
1721   } else
1722     OS.indent(16) << "n/a\n";
1723 
1724   for (MemoryAccess *Access : MemAccs)
1725     Access->print(OS);
1726 
1727   if (PrintInstructions)
1728     printInstructions(OS.indent(12));
1729 }
1730 
1731 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1732 LLVM_DUMP_METHOD void ScopStmt::dump() const { print(dbgs(), true); }
1733 #endif
1734 
1735 void ScopStmt::removeAccessData(MemoryAccess *MA) {
1736   if (MA->isRead() && MA->isOriginalValueKind()) {
1737     bool Found = ValueReads.erase(MA->getAccessValue());
1738     (void)Found;
1739     assert(Found && "Expected access data not found");
1740   }
1741   if (MA->isWrite() && MA->isOriginalValueKind()) {
1742     bool Found = ValueWrites.erase(cast<Instruction>(MA->getAccessValue()));
1743     (void)Found;
1744     assert(Found && "Expected access data not found");
1745   }
1746   if (MA->isWrite() && MA->isOriginalAnyPHIKind()) {
1747     bool Found = PHIWrites.erase(cast<PHINode>(MA->getAccessInstruction()));
1748     (void)Found;
1749     assert(Found && "Expected access data not found");
1750   }
1751   if (MA->isRead() && MA->isOriginalAnyPHIKind()) {
1752     bool Found = PHIReads.erase(cast<PHINode>(MA->getAccessInstruction()));
1753     (void)Found;
1754     assert(Found && "Expected access data not found");
1755   }
1756 }
1757 
1758 void ScopStmt::removeMemoryAccess(MemoryAccess *MA) {
1759   // Remove the memory accesses from this statement together with all scalar
1760   // accesses that were caused by it. MemoryKind::Value READs have no access
1761   // instruction, hence would not be removed by this function. However, it is
1762   // only used for invariant LoadInst accesses, its arguments are always affine,
1763   // hence synthesizable, and therefore there are no MemoryKind::Value READ
1764   // accesses to be removed.
1765   auto Predicate = [&](MemoryAccess *Acc) {
1766     return Acc->getAccessInstruction() == MA->getAccessInstruction();
1767   };
1768   for (auto *MA : MemAccs) {
1769     if (Predicate(MA)) {
1770       removeAccessData(MA);
1771       Parent.removeAccessData(MA);
1772     }
1773   }
1774   MemAccs.erase(std::remove_if(MemAccs.begin(), MemAccs.end(), Predicate),
1775                 MemAccs.end());
1776   InstructionToAccess.erase(MA->getAccessInstruction());
1777 }
1778 
1779 void ScopStmt::removeSingleMemoryAccess(MemoryAccess *MA, bool AfterHoisting) {
1780   if (AfterHoisting) {
1781     auto MAIt = std::find(MemAccs.begin(), MemAccs.end(), MA);
1782     assert(MAIt != MemAccs.end());
1783     MemAccs.erase(MAIt);
1784 
1785     removeAccessData(MA);
1786     Parent.removeAccessData(MA);
1787   }
1788 
1789   auto It = InstructionToAccess.find(MA->getAccessInstruction());
1790   if (It != InstructionToAccess.end()) {
1791     It->second.remove(MA);
1792     if (It->second.empty())
1793       InstructionToAccess.erase(MA->getAccessInstruction());
1794   }
1795 }
1796 
1797 MemoryAccess *ScopStmt::ensureValueRead(Value *V) {
1798   MemoryAccess *Access = lookupInputAccessOf(V);
1799   if (Access)
1800     return Access;
1801 
1802   ScopArrayInfo *SAI =
1803       Parent.getOrCreateScopArrayInfo(V, V->getType(), {}, MemoryKind::Value);
1804   Access = new MemoryAccess(this, nullptr, MemoryAccess::READ, V, V->getType(),
1805                             true, {}, {}, V, MemoryKind::Value);
1806   Parent.addAccessFunction(Access);
1807   Access->buildAccessRelation(SAI);
1808   addAccess(Access);
1809   Parent.addAccessData(Access);
1810   return Access;
1811 }
1812 
1813 raw_ostream &polly::operator<<(raw_ostream &OS, const ScopStmt &S) {
1814   S.print(OS, PollyPrintInstructions);
1815   return OS;
1816 }
1817 
1818 //===----------------------------------------------------------------------===//
1819 /// Scop class implement
1820 
1821 void Scop::setContext(isl::set NewContext) {
1822   Context = NewContext.align_params(Context.get_space());
1823 }
1824 
1825 namespace {
1826 
1827 /// Remap parameter values but keep AddRecs valid wrt. invariant loads.
1828 struct SCEVSensitiveParameterRewriter
1829     : public SCEVRewriteVisitor<SCEVSensitiveParameterRewriter> {
1830   const ValueToValueMap &VMap;
1831 
1832 public:
1833   SCEVSensitiveParameterRewriter(const ValueToValueMap &VMap,
1834                                  ScalarEvolution &SE)
1835       : SCEVRewriteVisitor(SE), VMap(VMap) {}
1836 
1837   static const SCEV *rewrite(const SCEV *E, ScalarEvolution &SE,
1838                              const ValueToValueMap &VMap) {
1839     SCEVSensitiveParameterRewriter SSPR(VMap, SE);
1840     return SSPR.visit(E);
1841   }
1842 
1843   const SCEV *visitAddRecExpr(const SCEVAddRecExpr *E) {
1844     auto *Start = visit(E->getStart());
1845     auto *AddRec = SE.getAddRecExpr(SE.getConstant(E->getType(), 0),
1846                                     visit(E->getStepRecurrence(SE)),
1847                                     E->getLoop(), SCEV::FlagAnyWrap);
1848     return SE.getAddExpr(Start, AddRec);
1849   }
1850 
1851   const SCEV *visitUnknown(const SCEVUnknown *E) {
1852     if (auto *NewValue = VMap.lookup(E->getValue()))
1853       return SE.getUnknown(NewValue);
1854     return E;
1855   }
1856 };
1857 
1858 /// Check whether we should remap a SCEV expression.
1859 struct SCEVFindInsideScop : public SCEVTraversal<SCEVFindInsideScop> {
1860   const ValueToValueMap &VMap;
1861   bool FoundInside = false;
1862   const Scop *S;
1863 
1864 public:
1865   SCEVFindInsideScop(const ValueToValueMap &VMap, ScalarEvolution &SE,
1866                      const Scop *S)
1867       : SCEVTraversal(*this), VMap(VMap), S(S) {}
1868 
1869   static bool hasVariant(const SCEV *E, ScalarEvolution &SE,
1870                          const ValueToValueMap &VMap, const Scop *S) {
1871     SCEVFindInsideScop SFIS(VMap, SE, S);
1872     SFIS.visitAll(E);
1873     return SFIS.FoundInside;
1874   }
1875 
1876   bool follow(const SCEV *E) {
1877     if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(E)) {
1878       FoundInside |= S->getRegion().contains(AddRec->getLoop());
1879     } else if (auto *Unknown = dyn_cast<SCEVUnknown>(E)) {
1880       if (Instruction *I = dyn_cast<Instruction>(Unknown->getValue()))
1881         FoundInside |= S->getRegion().contains(I) && !VMap.count(I);
1882     }
1883     return !FoundInside;
1884   }
1885 
1886   bool isDone() { return FoundInside; }
1887 };
1888 } // end anonymous namespace
1889 
1890 const SCEV *Scop::getRepresentingInvariantLoadSCEV(const SCEV *E) const {
1891   // Check whether it makes sense to rewrite the SCEV.  (ScalarEvolution
1892   // doesn't like addition between an AddRec and an expression that
1893   // doesn't have a dominance relationship with it.)
1894   if (SCEVFindInsideScop::hasVariant(E, *SE, InvEquivClassVMap, this))
1895     return E;
1896 
1897   // Rewrite SCEV.
1898   return SCEVSensitiveParameterRewriter::rewrite(E, *SE, InvEquivClassVMap);
1899 }
1900 
1901 // This table of function names is used to translate parameter names in more
1902 // human-readable names. This makes it easier to interpret Polly analysis
1903 // results.
1904 StringMap<std::string> KnownNames = {
1905     {"_Z13get_global_idj", "global_id"},
1906     {"_Z12get_local_idj", "local_id"},
1907     {"_Z15get_global_sizej", "global_size"},
1908     {"_Z14get_local_sizej", "local_size"},
1909     {"_Z12get_work_dimv", "work_dim"},
1910     {"_Z17get_global_offsetj", "global_offset"},
1911     {"_Z12get_group_idj", "group_id"},
1912     {"_Z14get_num_groupsj", "num_groups"},
1913 };
1914 
1915 static std::string getCallParamName(CallInst *Call) {
1916   std::string Result;
1917   raw_string_ostream OS(Result);
1918   std::string Name = Call->getCalledFunction()->getName();
1919 
1920   auto Iterator = KnownNames.find(Name);
1921   if (Iterator != KnownNames.end())
1922     Name = "__" + Iterator->getValue();
1923   OS << Name;
1924   for (auto &Operand : Call->arg_operands()) {
1925     ConstantInt *Op = cast<ConstantInt>(&Operand);
1926     OS << "_" << Op->getValue();
1927   }
1928   OS.flush();
1929   return Result;
1930 }
1931 
1932 void Scop::createParameterId(const SCEV *Parameter) {
1933   assert(Parameters.count(Parameter));
1934   assert(!ParameterIds.count(Parameter));
1935 
1936   std::string ParameterName = "p_" + std::to_string(getNumParams() - 1);
1937 
1938   if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
1939     Value *Val = ValueParameter->getValue();
1940     CallInst *Call = dyn_cast<CallInst>(Val);
1941 
1942     if (Call && isConstCall(Call)) {
1943       ParameterName = getCallParamName(Call);
1944     } else if (UseInstructionNames) {
1945       // If this parameter references a specific Value and this value has a name
1946       // we use this name as it is likely to be unique and more useful than just
1947       // a number.
1948       if (Val->hasName())
1949         ParameterName = Val->getName();
1950       else if (LoadInst *LI = dyn_cast<LoadInst>(Val)) {
1951         auto *LoadOrigin = LI->getPointerOperand()->stripInBoundsOffsets();
1952         if (LoadOrigin->hasName()) {
1953           ParameterName += "_loaded_from_";
1954           ParameterName +=
1955               LI->getPointerOperand()->stripInBoundsOffsets()->getName();
1956         }
1957       }
1958     }
1959 
1960     ParameterName = getIslCompatibleName("", ParameterName, "");
1961   }
1962 
1963   isl::id Id = isl::id::alloc(getIslCtx(), ParameterName,
1964                               const_cast<void *>((const void *)Parameter));
1965   ParameterIds[Parameter] = Id;
1966 }
1967 
1968 void Scop::addParams(const ParameterSetTy &NewParameters) {
1969   for (const SCEV *Parameter : NewParameters) {
1970     // Normalize the SCEV to get the representing element for an invariant load.
1971     Parameter = extractConstantFactor(Parameter, *SE).second;
1972     Parameter = getRepresentingInvariantLoadSCEV(Parameter);
1973 
1974     if (Parameters.insert(Parameter))
1975       createParameterId(Parameter);
1976   }
1977 }
1978 
1979 isl::id Scop::getIdForParam(const SCEV *Parameter) const {
1980   // Normalize the SCEV to get the representing element for an invariant load.
1981   Parameter = getRepresentingInvariantLoadSCEV(Parameter);
1982   return ParameterIds.lookup(Parameter);
1983 }
1984 
1985 isl::set Scop::addNonEmptyDomainConstraints(isl::set C) const {
1986   isl::set DomainContext = getDomains().params();
1987   return C.intersect_params(DomainContext);
1988 }
1989 
1990 bool Scop::isDominatedBy(const DominatorTree &DT, BasicBlock *BB) const {
1991   return DT.dominates(BB, getEntry());
1992 }
1993 
1994 void Scop::addUserAssumptions(
1995     AssumptionCache &AC, DominatorTree &DT, LoopInfo &LI,
1996     DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
1997   for (auto &Assumption : AC.assumptions()) {
1998     auto *CI = dyn_cast_or_null<CallInst>(Assumption);
1999     if (!CI || CI->getNumArgOperands() != 1)
2000       continue;
2001 
2002     bool InScop = contains(CI);
2003     if (!InScop && !isDominatedBy(DT, CI->getParent()))
2004       continue;
2005 
2006     auto *L = LI.getLoopFor(CI->getParent());
2007     auto *Val = CI->getArgOperand(0);
2008     ParameterSetTy DetectedParams;
2009     if (!isAffineConstraint(Val, &R, L, *SE, DetectedParams)) {
2010       ORE.emit(
2011           OptimizationRemarkAnalysis(DEBUG_TYPE, "IgnoreUserAssumption", CI)
2012           << "Non-affine user assumption ignored.");
2013       continue;
2014     }
2015 
2016     // Collect all newly introduced parameters.
2017     ParameterSetTy NewParams;
2018     for (auto *Param : DetectedParams) {
2019       Param = extractConstantFactor(Param, *SE).second;
2020       Param = getRepresentingInvariantLoadSCEV(Param);
2021       if (Parameters.count(Param))
2022         continue;
2023       NewParams.insert(Param);
2024     }
2025 
2026     SmallVector<isl_set *, 2> ConditionSets;
2027     auto *TI = InScop ? CI->getParent()->getTerminator() : nullptr;
2028     BasicBlock *BB = InScop ? CI->getParent() : getRegion().getEntry();
2029     auto *Dom = InScop ? DomainMap[BB].copy() : Context.copy();
2030     assert(Dom && "Cannot propagate a nullptr.");
2031     bool Valid = buildConditionSets(*this, BB, Val, TI, L, Dom,
2032                                     InvalidDomainMap, ConditionSets);
2033     isl_set_free(Dom);
2034 
2035     if (!Valid)
2036       continue;
2037 
2038     isl_set *AssumptionCtx = nullptr;
2039     if (InScop) {
2040       AssumptionCtx = isl_set_complement(isl_set_params(ConditionSets[1]));
2041       isl_set_free(ConditionSets[0]);
2042     } else {
2043       AssumptionCtx = isl_set_complement(ConditionSets[1]);
2044       AssumptionCtx = isl_set_intersect(AssumptionCtx, ConditionSets[0]);
2045     }
2046 
2047     // Project out newly introduced parameters as they are not otherwise useful.
2048     if (!NewParams.empty()) {
2049       for (unsigned u = 0; u < isl_set_n_param(AssumptionCtx); u++) {
2050         auto *Id = isl_set_get_dim_id(AssumptionCtx, isl_dim_param, u);
2051         auto *Param = static_cast<const SCEV *>(isl_id_get_user(Id));
2052         isl_id_free(Id);
2053 
2054         if (!NewParams.count(Param))
2055           continue;
2056 
2057         AssumptionCtx =
2058             isl_set_project_out(AssumptionCtx, isl_dim_param, u--, 1);
2059       }
2060     }
2061     ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "UserAssumption", CI)
2062              << "Use user assumption: " << stringFromIslObj(AssumptionCtx));
2063     Context = Context.intersect(isl::manage(AssumptionCtx));
2064   }
2065 }
2066 
2067 void Scop::addUserContext() {
2068   if (UserContextStr.empty())
2069     return;
2070 
2071   isl::set UserContext = isl::set(getIslCtx(), UserContextStr.c_str());
2072   isl::space Space = getParamSpace();
2073   if (Space.dim(isl::dim::param) != UserContext.dim(isl::dim::param)) {
2074     std::string SpaceStr = Space.to_str();
2075     errs() << "Error: the context provided in -polly-context has not the same "
2076            << "number of dimensions than the computed context. Due to this "
2077            << "mismatch, the -polly-context option is ignored. Please provide "
2078            << "the context in the parameter space: " << SpaceStr << ".\n";
2079     return;
2080   }
2081 
2082   for (unsigned i = 0; i < Space.dim(isl::dim::param); i++) {
2083     std::string NameContext = Context.get_dim_name(isl::dim::param, i);
2084     std::string NameUserContext = UserContext.get_dim_name(isl::dim::param, i);
2085 
2086     if (NameContext != NameUserContext) {
2087       std::string SpaceStr = Space.to_str();
2088       errs() << "Error: the name of dimension " << i
2089              << " provided in -polly-context "
2090              << "is '" << NameUserContext << "', but the name in the computed "
2091              << "context is '" << NameContext
2092              << "'. Due to this name mismatch, "
2093              << "the -polly-context option is ignored. Please provide "
2094              << "the context in the parameter space: " << SpaceStr << ".\n";
2095       return;
2096     }
2097 
2098     UserContext = UserContext.set_dim_id(isl::dim::param, i,
2099                                          Space.get_dim_id(isl::dim::param, i));
2100   }
2101 
2102   Context = Context.intersect(UserContext);
2103 }
2104 
2105 void Scop::buildInvariantEquivalenceClasses() {
2106   DenseMap<std::pair<const SCEV *, Type *>, LoadInst *> EquivClasses;
2107 
2108   const InvariantLoadsSetTy &RIL = getRequiredInvariantLoads();
2109   for (LoadInst *LInst : RIL) {
2110     const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
2111 
2112     Type *Ty = LInst->getType();
2113     LoadInst *&ClassRep = EquivClasses[std::make_pair(PointerSCEV, Ty)];
2114     if (ClassRep) {
2115       InvEquivClassVMap[LInst] = ClassRep;
2116       continue;
2117     }
2118 
2119     ClassRep = LInst;
2120     InvariantEquivClasses.emplace_back(
2121         InvariantEquivClassTy{PointerSCEV, MemoryAccessList(), nullptr, Ty});
2122   }
2123 }
2124 
2125 void Scop::buildContext() {
2126   isl::space Space = isl::space::params_alloc(getIslCtx(), 0);
2127   Context = isl::set::universe(Space);
2128   InvalidContext = isl::set::empty(Space);
2129   AssumedContext = isl::set::universe(Space);
2130 }
2131 
2132 void Scop::addParameterBounds() {
2133   unsigned PDim = 0;
2134   for (auto *Parameter : Parameters) {
2135     ConstantRange SRange = SE->getSignedRange(Parameter);
2136     Context = addRangeBoundsToSet(Context, SRange, PDim++, isl::dim::param);
2137   }
2138 }
2139 
2140 static std::vector<isl::id> getFortranArrayIds(Scop::array_range Arrays) {
2141   std::vector<isl::id> OutermostSizeIds;
2142   for (auto Array : Arrays) {
2143     // To check if an array is a Fortran array, we check if it has a isl_pw_aff
2144     // for its outermost dimension. Fortran arrays will have this since the
2145     // outermost dimension size can be picked up from their runtime description.
2146     // TODO: actually need to check if it has a FAD, but for now this works.
2147     if (Array->getNumberOfDimensions() > 0) {
2148       isl::pw_aff PwAff = Array->getDimensionSizePw(0);
2149       if (!PwAff)
2150         continue;
2151 
2152       isl::id Id = PwAff.get_dim_id(isl::dim::param, 0);
2153       assert(!Id.is_null() &&
2154              "Invalid Id for PwAff expression in Fortran array");
2155       OutermostSizeIds.push_back(Id);
2156     }
2157   }
2158   return OutermostSizeIds;
2159 }
2160 
2161 // The FORTRAN array size parameters are known to be non-negative.
2162 static isl::set boundFortranArrayParams(isl::set Context,
2163                                         Scop::array_range Arrays) {
2164   std::vector<isl::id> OutermostSizeIds;
2165   OutermostSizeIds = getFortranArrayIds(Arrays);
2166 
2167   for (isl::id Id : OutermostSizeIds) {
2168     int dim = Context.find_dim_by_id(isl::dim::param, Id);
2169     Context = Context.lower_bound_si(isl::dim::param, dim, 0);
2170   }
2171 
2172   return Context;
2173 }
2174 
2175 void Scop::realignParams() {
2176   if (PollyIgnoreParamBounds)
2177     return;
2178 
2179   // Add all parameters into a common model.
2180   isl::space Space = getFullParamSpace();
2181 
2182   // Align the parameters of all data structures to the model.
2183   Context = Context.align_params(Space);
2184 
2185   // Bound the size of the fortran array dimensions.
2186   Context = boundFortranArrayParams(Context, arrays());
2187 
2188   // As all parameters are known add bounds to them.
2189   addParameterBounds();
2190 
2191   for (ScopStmt &Stmt : *this)
2192     Stmt.realignParams();
2193   // Simplify the schedule according to the context too.
2194   Schedule = Schedule.gist_domain_params(getContext());
2195 }
2196 
2197 static isl::set simplifyAssumptionContext(isl::set AssumptionContext,
2198                                           const Scop &S) {
2199   // If we have modeled all blocks in the SCoP that have side effects we can
2200   // simplify the context with the constraints that are needed for anything to
2201   // be executed at all. However, if we have error blocks in the SCoP we already
2202   // assumed some parameter combinations cannot occur and removed them from the
2203   // domains, thus we cannot use the remaining domain to simplify the
2204   // assumptions.
2205   if (!S.hasErrorBlock()) {
2206     auto DomainParameters = S.getDomains().params();
2207     AssumptionContext = AssumptionContext.gist_params(DomainParameters);
2208   }
2209 
2210   AssumptionContext = AssumptionContext.gist_params(S.getContext());
2211   return AssumptionContext;
2212 }
2213 
2214 void Scop::simplifyContexts() {
2215   // The parameter constraints of the iteration domains give us a set of
2216   // constraints that need to hold for all cases where at least a single
2217   // statement iteration is executed in the whole scop. We now simplify the
2218   // assumed context under the assumption that such constraints hold and at
2219   // least a single statement iteration is executed. For cases where no
2220   // statement instances are executed, the assumptions we have taken about
2221   // the executed code do not matter and can be changed.
2222   //
2223   // WARNING: This only holds if the assumptions we have taken do not reduce
2224   //          the set of statement instances that are executed. Otherwise we
2225   //          may run into a case where the iteration domains suggest that
2226   //          for a certain set of parameter constraints no code is executed,
2227   //          but in the original program some computation would have been
2228   //          performed. In such a case, modifying the run-time conditions and
2229   //          possibly influencing the run-time check may cause certain scops
2230   //          to not be executed.
2231   //
2232   // Example:
2233   //
2234   //   When delinearizing the following code:
2235   //
2236   //     for (long i = 0; i < 100; i++)
2237   //       for (long j = 0; j < m; j++)
2238   //         A[i+p][j] = 1.0;
2239   //
2240   //   we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
2241   //   otherwise we would access out of bound data. Now, knowing that code is
2242   //   only executed for the case m >= 0, it is sufficient to assume p >= 0.
2243   AssumedContext = simplifyAssumptionContext(AssumedContext, *this);
2244   InvalidContext = InvalidContext.align_params(getParamSpace());
2245 }
2246 
2247 /// Add the minimal/maximal access in @p Set to @p User.
2248 ///
2249 /// @return True if more accesses should be added, false if we reached the
2250 ///         maximal number of run-time checks to be generated.
2251 static bool buildMinMaxAccess(isl::set Set,
2252                               Scop::MinMaxVectorTy &MinMaxAccesses, Scop &S) {
2253   isl::pw_multi_aff MinPMA, MaxPMA;
2254   isl::pw_aff LastDimAff;
2255   isl::aff OneAff;
2256   unsigned Pos;
2257 
2258   Set = Set.remove_divs();
2259   polly::simplify(Set);
2260 
2261   if (Set.n_basic_set() > RunTimeChecksMaxAccessDisjuncts)
2262     Set = Set.simple_hull();
2263 
2264   // Restrict the number of parameters involved in the access as the lexmin/
2265   // lexmax computation will take too long if this number is high.
2266   //
2267   // Experiments with a simple test case using an i7 4800MQ:
2268   //
2269   //  #Parameters involved | Time (in sec)
2270   //            6          |     0.01
2271   //            7          |     0.04
2272   //            8          |     0.12
2273   //            9          |     0.40
2274   //           10          |     1.54
2275   //           11          |     6.78
2276   //           12          |    30.38
2277   //
2278   if (isl_set_n_param(Set.get()) > RunTimeChecksMaxParameters) {
2279     unsigned InvolvedParams = 0;
2280     for (unsigned u = 0, e = isl_set_n_param(Set.get()); u < e; u++)
2281       if (Set.involves_dims(isl::dim::param, u, 1))
2282         InvolvedParams++;
2283 
2284     if (InvolvedParams > RunTimeChecksMaxParameters)
2285       return false;
2286   }
2287 
2288   MinPMA = Set.lexmin_pw_multi_aff();
2289   MaxPMA = Set.lexmax_pw_multi_aff();
2290 
2291   MinPMA = MinPMA.coalesce();
2292   MaxPMA = MaxPMA.coalesce();
2293 
2294   // Adjust the last dimension of the maximal access by one as we want to
2295   // enclose the accessed memory region by MinPMA and MaxPMA. The pointer
2296   // we test during code generation might now point after the end of the
2297   // allocated array but we will never dereference it anyway.
2298   assert((!MaxPMA || MaxPMA.dim(isl::dim::out)) &&
2299          "Assumed at least one output dimension");
2300 
2301   Pos = MaxPMA.dim(isl::dim::out) - 1;
2302   LastDimAff = MaxPMA.get_pw_aff(Pos);
2303   OneAff = isl::aff(isl::local_space(LastDimAff.get_domain_space()));
2304   OneAff = OneAff.add_constant_si(1);
2305   LastDimAff = LastDimAff.add(OneAff);
2306   MaxPMA = MaxPMA.set_pw_aff(Pos, LastDimAff);
2307 
2308   if (!MinPMA || !MaxPMA)
2309     return false;
2310 
2311   MinMaxAccesses.push_back(std::make_pair(MinPMA, MaxPMA));
2312 
2313   return true;
2314 }
2315 
2316 static isl::set getAccessDomain(MemoryAccess *MA) {
2317   isl::set Domain = MA->getStatement()->getDomain();
2318   Domain = Domain.project_out(isl::dim::set, 0, Domain.n_dim());
2319   return Domain.reset_tuple_id();
2320 }
2321 
2322 /// Wrapper function to calculate minimal/maximal accesses to each array.
2323 static bool calculateMinMaxAccess(Scop::AliasGroupTy AliasGroup, Scop &S,
2324                                   Scop::MinMaxVectorTy &MinMaxAccesses) {
2325   MinMaxAccesses.reserve(AliasGroup.size());
2326 
2327   isl::union_set Domains = S.getDomains();
2328   isl::union_map Accesses = isl::union_map::empty(S.getParamSpace());
2329 
2330   for (MemoryAccess *MA : AliasGroup)
2331     Accesses = Accesses.add_map(MA->getAccessRelation());
2332 
2333   Accesses = Accesses.intersect_domain(Domains);
2334   isl::union_set Locations = Accesses.range();
2335 
2336   bool LimitReached = false;
2337   for (isl::set Set : Locations.get_set_list()) {
2338     LimitReached |= !buildMinMaxAccess(Set, MinMaxAccesses, S);
2339     if (LimitReached)
2340       break;
2341   }
2342 
2343   return !LimitReached;
2344 }
2345 
2346 /// Helper to treat non-affine regions and basic blocks the same.
2347 ///
2348 ///{
2349 
2350 /// Return the block that is the representing block for @p RN.
2351 static inline BasicBlock *getRegionNodeBasicBlock(RegionNode *RN) {
2352   return RN->isSubRegion() ? RN->getNodeAs<Region>()->getEntry()
2353                            : RN->getNodeAs<BasicBlock>();
2354 }
2355 
2356 /// Return the @p idx'th block that is executed after @p RN.
2357 static inline BasicBlock *
2358 getRegionNodeSuccessor(RegionNode *RN, Instruction *TI, unsigned idx) {
2359   if (RN->isSubRegion()) {
2360     assert(idx == 0);
2361     return RN->getNodeAs<Region>()->getExit();
2362   }
2363   return TI->getSuccessor(idx);
2364 }
2365 
2366 /// Return the smallest loop surrounding @p RN.
2367 static inline Loop *getRegionNodeLoop(RegionNode *RN, LoopInfo &LI) {
2368   if (!RN->isSubRegion()) {
2369     BasicBlock *BB = RN->getNodeAs<BasicBlock>();
2370     Loop *L = LI.getLoopFor(BB);
2371 
2372     // Unreachable statements are not considered to belong to a LLVM loop, as
2373     // they are not part of an actual loop in the control flow graph.
2374     // Nevertheless, we handle certain unreachable statements that are common
2375     // when modeling run-time bounds checks as being part of the loop to be
2376     // able to model them and to later eliminate the run-time bounds checks.
2377     //
2378     // Specifically, for basic blocks that terminate in an unreachable and
2379     // where the immediate predecessor is part of a loop, we assume these
2380     // basic blocks belong to the loop the predecessor belongs to. This
2381     // allows us to model the following code.
2382     //
2383     // for (i = 0; i < N; i++) {
2384     //   if (i > 1024)
2385     //     abort();            <- this abort might be translated to an
2386     //                            unreachable
2387     //
2388     //   A[i] = ...
2389     // }
2390     if (!L && isa<UnreachableInst>(BB->getTerminator()) && BB->getPrevNode())
2391       L = LI.getLoopFor(BB->getPrevNode());
2392     return L;
2393   }
2394 
2395   Region *NonAffineSubRegion = RN->getNodeAs<Region>();
2396   Loop *L = LI.getLoopFor(NonAffineSubRegion->getEntry());
2397   while (L && NonAffineSubRegion->contains(L))
2398     L = L->getParentLoop();
2399   return L;
2400 }
2401 
2402 /// Get the number of blocks in @p L.
2403 ///
2404 /// The number of blocks in a loop are the number of basic blocks actually
2405 /// belonging to the loop, as well as all single basic blocks that the loop
2406 /// exits to and which terminate in an unreachable instruction. We do not
2407 /// allow such basic blocks in the exit of a scop, hence they belong to the
2408 /// scop and represent run-time conditions which we want to model and
2409 /// subsequently speculate away.
2410 ///
2411 /// @see getRegionNodeLoop for additional details.
2412 unsigned getNumBlocksInLoop(Loop *L) {
2413   unsigned NumBlocks = L->getNumBlocks();
2414   SmallVector<BasicBlock *, 4> ExitBlocks;
2415   L->getExitBlocks(ExitBlocks);
2416 
2417   for (auto ExitBlock : ExitBlocks) {
2418     if (isa<UnreachableInst>(ExitBlock->getTerminator()))
2419       NumBlocks++;
2420   }
2421   return NumBlocks;
2422 }
2423 
2424 static inline unsigned getNumBlocksInRegionNode(RegionNode *RN) {
2425   if (!RN->isSubRegion())
2426     return 1;
2427 
2428   Region *R = RN->getNodeAs<Region>();
2429   return std::distance(R->block_begin(), R->block_end());
2430 }
2431 
2432 static bool containsErrorBlock(RegionNode *RN, const Region &R, LoopInfo &LI,
2433                                const DominatorTree &DT) {
2434   if (!RN->isSubRegion())
2435     return isErrorBlock(*RN->getNodeAs<BasicBlock>(), R, LI, DT);
2436   for (BasicBlock *BB : RN->getNodeAs<Region>()->blocks())
2437     if (isErrorBlock(*BB, R, LI, DT))
2438       return true;
2439   return false;
2440 }
2441 
2442 ///}
2443 
2444 isl::set Scop::getDomainConditions(const ScopStmt *Stmt) const {
2445   return getDomainConditions(Stmt->getEntryBlock());
2446 }
2447 
2448 isl::set Scop::getDomainConditions(BasicBlock *BB) const {
2449   auto DIt = DomainMap.find(BB);
2450   if (DIt != DomainMap.end())
2451     return DIt->getSecond();
2452 
2453   auto &RI = *R.getRegionInfo();
2454   auto *BBR = RI.getRegionFor(BB);
2455   while (BBR->getEntry() == BB)
2456     BBR = BBR->getParent();
2457   return getDomainConditions(BBR->getEntry());
2458 }
2459 
2460 bool Scop::buildDomains(Region *R, DominatorTree &DT, LoopInfo &LI,
2461                         DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
2462   bool IsOnlyNonAffineRegion = isNonAffineSubRegion(R);
2463   auto *EntryBB = R->getEntry();
2464   auto *L = IsOnlyNonAffineRegion ? nullptr : LI.getLoopFor(EntryBB);
2465   int LD = getRelativeLoopDepth(L);
2466   auto *S = isl_set_universe(isl_space_set_alloc(getIslCtx().get(), 0, LD + 1));
2467 
2468   while (LD-- >= 0) {
2469     L = L->getParentLoop();
2470   }
2471 
2472   InvalidDomainMap[EntryBB] = isl::manage(isl_set_empty(isl_set_get_space(S)));
2473   DomainMap[EntryBB] = isl::manage(S);
2474 
2475   if (IsOnlyNonAffineRegion)
2476     return !containsErrorBlock(R->getNode(), *R, LI, DT);
2477 
2478   if (!buildDomainsWithBranchConstraints(R, DT, LI, InvalidDomainMap))
2479     return false;
2480 
2481   if (!propagateDomainConstraints(R, DT, LI, InvalidDomainMap))
2482     return false;
2483 
2484   // Error blocks and blocks dominated by them have been assumed to never be
2485   // executed. Representing them in the Scop does not add any value. In fact,
2486   // it is likely to cause issues during construction of the ScopStmts. The
2487   // contents of error blocks have not been verified to be expressible and
2488   // will cause problems when building up a ScopStmt for them.
2489   // Furthermore, basic blocks dominated by error blocks may reference
2490   // instructions in the error block which, if the error block is not modeled,
2491   // can themselves not be constructed properly. To this end we will replace
2492   // the domains of error blocks and those only reachable via error blocks
2493   // with an empty set. Additionally, we will record for each block under which
2494   // parameter combination it would be reached via an error block in its
2495   // InvalidDomain. This information is needed during load hoisting.
2496   if (!propagateInvalidStmtDomains(R, DT, LI, InvalidDomainMap))
2497     return false;
2498 
2499   return true;
2500 }
2501 
2502 /// Adjust the dimensions of @p Dom that was constructed for @p OldL
2503 ///        to be compatible to domains constructed for loop @p NewL.
2504 ///
2505 /// This function assumes @p NewL and @p OldL are equal or there is a CFG
2506 /// edge from @p OldL to @p NewL.
2507 static isl::set adjustDomainDimensions(Scop &S, isl::set Dom, Loop *OldL,
2508                                        Loop *NewL) {
2509   // If the loops are the same there is nothing to do.
2510   if (NewL == OldL)
2511     return Dom;
2512 
2513   int OldDepth = S.getRelativeLoopDepth(OldL);
2514   int NewDepth = S.getRelativeLoopDepth(NewL);
2515   // If both loops are non-affine loops there is nothing to do.
2516   if (OldDepth == -1 && NewDepth == -1)
2517     return Dom;
2518 
2519   // Distinguish three cases:
2520   //   1) The depth is the same but the loops are not.
2521   //      => One loop was left one was entered.
2522   //   2) The depth increased from OldL to NewL.
2523   //      => One loop was entered, none was left.
2524   //   3) The depth decreased from OldL to NewL.
2525   //      => Loops were left were difference of the depths defines how many.
2526   if (OldDepth == NewDepth) {
2527     assert(OldL->getParentLoop() == NewL->getParentLoop());
2528     Dom = Dom.project_out(isl::dim::set, NewDepth, 1);
2529     Dom = Dom.add_dims(isl::dim::set, 1);
2530   } else if (OldDepth < NewDepth) {
2531     assert(OldDepth + 1 == NewDepth);
2532     auto &R = S.getRegion();
2533     (void)R;
2534     assert(NewL->getParentLoop() == OldL ||
2535            ((!OldL || !R.contains(OldL)) && R.contains(NewL)));
2536     Dom = Dom.add_dims(isl::dim::set, 1);
2537   } else {
2538     assert(OldDepth > NewDepth);
2539     int Diff = OldDepth - NewDepth;
2540     int NumDim = Dom.n_dim();
2541     assert(NumDim >= Diff);
2542     Dom = Dom.project_out(isl::dim::set, NumDim - Diff, Diff);
2543   }
2544 
2545   return Dom;
2546 }
2547 
2548 bool Scop::propagateInvalidStmtDomains(
2549     Region *R, DominatorTree &DT, LoopInfo &LI,
2550     DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
2551   ReversePostOrderTraversal<Region *> RTraversal(R);
2552   for (auto *RN : RTraversal) {
2553 
2554     // Recurse for affine subregions but go on for basic blocks and non-affine
2555     // subregions.
2556     if (RN->isSubRegion()) {
2557       Region *SubRegion = RN->getNodeAs<Region>();
2558       if (!isNonAffineSubRegion(SubRegion)) {
2559         propagateInvalidStmtDomains(SubRegion, DT, LI, InvalidDomainMap);
2560         continue;
2561       }
2562     }
2563 
2564     bool ContainsErrorBlock = containsErrorBlock(RN, getRegion(), LI, DT);
2565     BasicBlock *BB = getRegionNodeBasicBlock(RN);
2566     isl::set &Domain = DomainMap[BB];
2567     assert(Domain && "Cannot propagate a nullptr");
2568 
2569     isl::set InvalidDomain = InvalidDomainMap[BB];
2570 
2571     bool IsInvalidBlock = ContainsErrorBlock || Domain.is_subset(InvalidDomain);
2572 
2573     if (!IsInvalidBlock) {
2574       InvalidDomain = InvalidDomain.intersect(Domain);
2575     } else {
2576       InvalidDomain = Domain;
2577       isl::set DomPar = Domain.params();
2578       recordAssumption(ERRORBLOCK, DomPar, BB->getTerminator()->getDebugLoc(),
2579                        AS_RESTRICTION);
2580       Domain = isl::set::empty(Domain.get_space());
2581     }
2582 
2583     if (InvalidDomain.is_empty()) {
2584       InvalidDomainMap[BB] = InvalidDomain;
2585       continue;
2586     }
2587 
2588     auto *BBLoop = getRegionNodeLoop(RN, LI);
2589     auto *TI = BB->getTerminator();
2590     unsigned NumSuccs = RN->isSubRegion() ? 1 : TI->getNumSuccessors();
2591     for (unsigned u = 0; u < NumSuccs; u++) {
2592       auto *SuccBB = getRegionNodeSuccessor(RN, TI, u);
2593 
2594       // Skip successors outside the SCoP.
2595       if (!contains(SuccBB))
2596         continue;
2597 
2598       // Skip backedges.
2599       if (DT.dominates(SuccBB, BB))
2600         continue;
2601 
2602       Loop *SuccBBLoop = getFirstNonBoxedLoopFor(SuccBB, LI, getBoxedLoops());
2603 
2604       auto AdjustedInvalidDomain =
2605           adjustDomainDimensions(*this, InvalidDomain, BBLoop, SuccBBLoop);
2606 
2607       isl::set SuccInvalidDomain = InvalidDomainMap[SuccBB];
2608       SuccInvalidDomain = SuccInvalidDomain.unite(AdjustedInvalidDomain);
2609       SuccInvalidDomain = SuccInvalidDomain.coalesce();
2610       unsigned NumConjucts = SuccInvalidDomain.n_basic_set();
2611 
2612       InvalidDomainMap[SuccBB] = SuccInvalidDomain;
2613 
2614       // Check if the maximal number of domain disjunctions was reached.
2615       // In case this happens we will bail.
2616       if (NumConjucts < MaxDisjunctsInDomain)
2617         continue;
2618 
2619       InvalidDomainMap.erase(BB);
2620       invalidate(COMPLEXITY, TI->getDebugLoc(), TI->getParent());
2621       return false;
2622     }
2623 
2624     InvalidDomainMap[BB] = InvalidDomain;
2625   }
2626 
2627   return true;
2628 }
2629 
2630 void Scop::propagateDomainConstraintsToRegionExit(
2631     BasicBlock *BB, Loop *BBLoop,
2632     SmallPtrSetImpl<BasicBlock *> &FinishedExitBlocks, LoopInfo &LI,
2633     DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
2634   // Check if the block @p BB is the entry of a region. If so we propagate it's
2635   // domain to the exit block of the region. Otherwise we are done.
2636   auto *RI = R.getRegionInfo();
2637   auto *BBReg = RI ? RI->getRegionFor(BB) : nullptr;
2638   auto *ExitBB = BBReg ? BBReg->getExit() : nullptr;
2639   if (!BBReg || BBReg->getEntry() != BB || !contains(ExitBB))
2640     return;
2641 
2642   // Do not propagate the domain if there is a loop backedge inside the region
2643   // that would prevent the exit block from being executed.
2644   auto *L = BBLoop;
2645   while (L && contains(L)) {
2646     SmallVector<BasicBlock *, 4> LatchBBs;
2647     BBLoop->getLoopLatches(LatchBBs);
2648     for (auto *LatchBB : LatchBBs)
2649       if (BB != LatchBB && BBReg->contains(LatchBB))
2650         return;
2651     L = L->getParentLoop();
2652   }
2653 
2654   isl::set Domain = DomainMap[BB];
2655   assert(Domain && "Cannot propagate a nullptr");
2656 
2657   Loop *ExitBBLoop = getFirstNonBoxedLoopFor(ExitBB, LI, getBoxedLoops());
2658 
2659   // Since the dimensions of @p BB and @p ExitBB might be different we have to
2660   // adjust the domain before we can propagate it.
2661   isl::set AdjustedDomain =
2662       adjustDomainDimensions(*this, Domain, BBLoop, ExitBBLoop);
2663   isl::set &ExitDomain = DomainMap[ExitBB];
2664 
2665   // If the exit domain is not yet created we set it otherwise we "add" the
2666   // current domain.
2667   ExitDomain = ExitDomain ? AdjustedDomain.unite(ExitDomain) : AdjustedDomain;
2668 
2669   // Initialize the invalid domain.
2670   InvalidDomainMap[ExitBB] = ExitDomain.empty(ExitDomain.get_space());
2671 
2672   FinishedExitBlocks.insert(ExitBB);
2673 }
2674 
2675 bool Scop::buildDomainsWithBranchConstraints(
2676     Region *R, DominatorTree &DT, LoopInfo &LI,
2677     DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
2678   // To create the domain for each block in R we iterate over all blocks and
2679   // subregions in R and propagate the conditions under which the current region
2680   // element is executed. To this end we iterate in reverse post order over R as
2681   // it ensures that we first visit all predecessors of a region node (either a
2682   // basic block or a subregion) before we visit the region node itself.
2683   // Initially, only the domain for the SCoP region entry block is set and from
2684   // there we propagate the current domain to all successors, however we add the
2685   // condition that the successor is actually executed next.
2686   // As we are only interested in non-loop carried constraints here we can
2687   // simply skip loop back edges.
2688 
2689   SmallPtrSet<BasicBlock *, 8> FinishedExitBlocks;
2690   ReversePostOrderTraversal<Region *> RTraversal(R);
2691   for (auto *RN : RTraversal) {
2692     // Recurse for affine subregions but go on for basic blocks and non-affine
2693     // subregions.
2694     if (RN->isSubRegion()) {
2695       Region *SubRegion = RN->getNodeAs<Region>();
2696       if (!isNonAffineSubRegion(SubRegion)) {
2697         if (!buildDomainsWithBranchConstraints(SubRegion, DT, LI,
2698                                                InvalidDomainMap))
2699           return false;
2700         continue;
2701       }
2702     }
2703 
2704     if (containsErrorBlock(RN, getRegion(), LI, DT))
2705       HasErrorBlock = true;
2706 
2707     BasicBlock *BB = getRegionNodeBasicBlock(RN);
2708     Instruction *TI = BB->getTerminator();
2709 
2710     if (isa<UnreachableInst>(TI))
2711       continue;
2712 
2713     isl::set Domain = DomainMap.lookup(BB);
2714     if (!Domain)
2715       continue;
2716     MaxLoopDepth = std::max(MaxLoopDepth, isl_set_n_dim(Domain.get()));
2717 
2718     auto *BBLoop = getRegionNodeLoop(RN, LI);
2719     // Propagate the domain from BB directly to blocks that have a superset
2720     // domain, at the moment only region exit nodes of regions that start in BB.
2721     propagateDomainConstraintsToRegionExit(BB, BBLoop, FinishedExitBlocks, LI,
2722                                            InvalidDomainMap);
2723 
2724     // If all successors of BB have been set a domain through the propagation
2725     // above we do not need to build condition sets but can just skip this
2726     // block. However, it is important to note that this is a local property
2727     // with regards to the region @p R. To this end FinishedExitBlocks is a
2728     // local variable.
2729     auto IsFinishedRegionExit = [&FinishedExitBlocks](BasicBlock *SuccBB) {
2730       return FinishedExitBlocks.count(SuccBB);
2731     };
2732     if (std::all_of(succ_begin(BB), succ_end(BB), IsFinishedRegionExit))
2733       continue;
2734 
2735     // Build the condition sets for the successor nodes of the current region
2736     // node. If it is a non-affine subregion we will always execute the single
2737     // exit node, hence the single entry node domain is the condition set. For
2738     // basic blocks we use the helper function buildConditionSets.
2739     SmallVector<isl_set *, 8> ConditionSets;
2740     if (RN->isSubRegion())
2741       ConditionSets.push_back(Domain.copy());
2742     else if (!buildConditionSets(*this, BB, TI, BBLoop, Domain.get(),
2743                                  InvalidDomainMap, ConditionSets))
2744       return false;
2745 
2746     // Now iterate over the successors and set their initial domain based on
2747     // their condition set. We skip back edges here and have to be careful when
2748     // we leave a loop not to keep constraints over a dimension that doesn't
2749     // exist anymore.
2750     assert(RN->isSubRegion() || TI->getNumSuccessors() == ConditionSets.size());
2751     for (unsigned u = 0, e = ConditionSets.size(); u < e; u++) {
2752       isl::set CondSet = isl::manage(ConditionSets[u]);
2753       BasicBlock *SuccBB = getRegionNodeSuccessor(RN, TI, u);
2754 
2755       // Skip blocks outside the region.
2756       if (!contains(SuccBB))
2757         continue;
2758 
2759       // If we propagate the domain of some block to "SuccBB" we do not have to
2760       // adjust the domain.
2761       if (FinishedExitBlocks.count(SuccBB))
2762         continue;
2763 
2764       // Skip back edges.
2765       if (DT.dominates(SuccBB, BB))
2766         continue;
2767 
2768       Loop *SuccBBLoop = getFirstNonBoxedLoopFor(SuccBB, LI, getBoxedLoops());
2769 
2770       CondSet = adjustDomainDimensions(*this, CondSet, BBLoop, SuccBBLoop);
2771 
2772       // Set the domain for the successor or merge it with an existing domain in
2773       // case there are multiple paths (without loop back edges) to the
2774       // successor block.
2775       isl::set &SuccDomain = DomainMap[SuccBB];
2776 
2777       if (SuccDomain) {
2778         SuccDomain = SuccDomain.unite(CondSet).coalesce();
2779       } else {
2780         // Initialize the invalid domain.
2781         InvalidDomainMap[SuccBB] = CondSet.empty(CondSet.get_space());
2782         SuccDomain = CondSet;
2783       }
2784 
2785       SuccDomain = SuccDomain.detect_equalities();
2786 
2787       // Check if the maximal number of domain disjunctions was reached.
2788       // In case this happens we will clean up and bail.
2789       if (SuccDomain.n_basic_set() < MaxDisjunctsInDomain)
2790         continue;
2791 
2792       invalidate(COMPLEXITY, DebugLoc());
2793       while (++u < ConditionSets.size())
2794         isl_set_free(ConditionSets[u]);
2795       return false;
2796     }
2797   }
2798 
2799   return true;
2800 }
2801 
2802 isl::set Scop::getPredecessorDomainConstraints(BasicBlock *BB, isl::set Domain,
2803                                                DominatorTree &DT,
2804                                                LoopInfo &LI) {
2805   // If @p BB is the ScopEntry we are done
2806   if (R.getEntry() == BB)
2807     return isl::set::universe(Domain.get_space());
2808 
2809   // The region info of this function.
2810   auto &RI = *R.getRegionInfo();
2811 
2812   Loop *BBLoop = getFirstNonBoxedLoopFor(BB, LI, getBoxedLoops());
2813 
2814   // A domain to collect all predecessor domains, thus all conditions under
2815   // which the block is executed. To this end we start with the empty domain.
2816   isl::set PredDom = isl::set::empty(Domain.get_space());
2817 
2818   // Set of regions of which the entry block domain has been propagated to BB.
2819   // all predecessors inside any of the regions can be skipped.
2820   SmallSet<Region *, 8> PropagatedRegions;
2821 
2822   for (auto *PredBB : predecessors(BB)) {
2823     // Skip backedges.
2824     if (DT.dominates(BB, PredBB))
2825       continue;
2826 
2827     // If the predecessor is in a region we used for propagation we can skip it.
2828     auto PredBBInRegion = [PredBB](Region *PR) { return PR->contains(PredBB); };
2829     if (std::any_of(PropagatedRegions.begin(), PropagatedRegions.end(),
2830                     PredBBInRegion)) {
2831       continue;
2832     }
2833 
2834     // Check if there is a valid region we can use for propagation, thus look
2835     // for a region that contains the predecessor and has @p BB as exit block.
2836     auto *PredR = RI.getRegionFor(PredBB);
2837     while (PredR->getExit() != BB && !PredR->contains(BB))
2838       PredR->getParent();
2839 
2840     // If a valid region for propagation was found use the entry of that region
2841     // for propagation, otherwise the PredBB directly.
2842     if (PredR->getExit() == BB) {
2843       PredBB = PredR->getEntry();
2844       PropagatedRegions.insert(PredR);
2845     }
2846 
2847     isl::set PredBBDom = getDomainConditions(PredBB);
2848     Loop *PredBBLoop = getFirstNonBoxedLoopFor(PredBB, LI, getBoxedLoops());
2849     PredBBDom = adjustDomainDimensions(*this, PredBBDom, PredBBLoop, BBLoop);
2850     PredDom = PredDom.unite(PredBBDom);
2851   }
2852 
2853   return PredDom;
2854 }
2855 
2856 bool Scop::propagateDomainConstraints(
2857     Region *R, DominatorTree &DT, LoopInfo &LI,
2858     DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
2859   // Iterate over the region R and propagate the domain constrains from the
2860   // predecessors to the current node. In contrast to the
2861   // buildDomainsWithBranchConstraints function, this one will pull the domain
2862   // information from the predecessors instead of pushing it to the successors.
2863   // Additionally, we assume the domains to be already present in the domain
2864   // map here. However, we iterate again in reverse post order so we know all
2865   // predecessors have been visited before a block or non-affine subregion is
2866   // visited.
2867 
2868   ReversePostOrderTraversal<Region *> RTraversal(R);
2869   for (auto *RN : RTraversal) {
2870     // Recurse for affine subregions but go on for basic blocks and non-affine
2871     // subregions.
2872     if (RN->isSubRegion()) {
2873       Region *SubRegion = RN->getNodeAs<Region>();
2874       if (!isNonAffineSubRegion(SubRegion)) {
2875         if (!propagateDomainConstraints(SubRegion, DT, LI, InvalidDomainMap))
2876           return false;
2877         continue;
2878       }
2879     }
2880 
2881     BasicBlock *BB = getRegionNodeBasicBlock(RN);
2882     isl::set &Domain = DomainMap[BB];
2883     assert(Domain);
2884 
2885     // Under the union of all predecessor conditions we can reach this block.
2886     isl::set PredDom = getPredecessorDomainConstraints(BB, Domain, DT, LI);
2887     Domain = Domain.intersect(PredDom).coalesce();
2888     Domain = Domain.align_params(getParamSpace());
2889 
2890     Loop *BBLoop = getRegionNodeLoop(RN, LI);
2891     if (BBLoop && BBLoop->getHeader() == BB && contains(BBLoop))
2892       if (!addLoopBoundsToHeaderDomain(BBLoop, LI, InvalidDomainMap))
2893         return false;
2894   }
2895 
2896   return true;
2897 }
2898 
2899 /// Create a map to map from a given iteration to a subsequent iteration.
2900 ///
2901 /// This map maps from SetSpace -> SetSpace where the dimensions @p Dim
2902 /// is incremented by one and all other dimensions are equal, e.g.,
2903 ///             [i0, i1, i2, i3] -> [i0, i1, i2 + 1, i3]
2904 ///
2905 /// if @p Dim is 2 and @p SetSpace has 4 dimensions.
2906 static isl::map createNextIterationMap(isl::space SetSpace, unsigned Dim) {
2907   isl::space MapSpace = SetSpace.map_from_set();
2908   isl::map NextIterationMap = isl::map::universe(MapSpace);
2909   for (unsigned u = 0; u < NextIterationMap.dim(isl::dim::in); u++)
2910     if (u != Dim)
2911       NextIterationMap =
2912           NextIterationMap.equate(isl::dim::in, u, isl::dim::out, u);
2913   isl::constraint C =
2914       isl::constraint::alloc_equality(isl::local_space(MapSpace));
2915   C = C.set_constant_si(1);
2916   C = C.set_coefficient_si(isl::dim::in, Dim, 1);
2917   C = C.set_coefficient_si(isl::dim::out, Dim, -1);
2918   NextIterationMap = NextIterationMap.add_constraint(C);
2919   return NextIterationMap;
2920 }
2921 
2922 bool Scop::addLoopBoundsToHeaderDomain(
2923     Loop *L, LoopInfo &LI, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
2924   int LoopDepth = getRelativeLoopDepth(L);
2925   assert(LoopDepth >= 0 && "Loop in region should have at least depth one");
2926 
2927   BasicBlock *HeaderBB = L->getHeader();
2928   assert(DomainMap.count(HeaderBB));
2929   isl::set &HeaderBBDom = DomainMap[HeaderBB];
2930 
2931   isl::map NextIterationMap =
2932       createNextIterationMap(HeaderBBDom.get_space(), LoopDepth);
2933 
2934   isl::set UnionBackedgeCondition = HeaderBBDom.empty(HeaderBBDom.get_space());
2935 
2936   SmallVector<BasicBlock *, 4> LatchBlocks;
2937   L->getLoopLatches(LatchBlocks);
2938 
2939   for (BasicBlock *LatchBB : LatchBlocks) {
2940     // If the latch is only reachable via error statements we skip it.
2941     isl::set LatchBBDom = DomainMap.lookup(LatchBB);
2942     if (!LatchBBDom)
2943       continue;
2944 
2945     isl::set BackedgeCondition = nullptr;
2946 
2947     Instruction *TI = LatchBB->getTerminator();
2948     BranchInst *BI = dyn_cast<BranchInst>(TI);
2949     assert(BI && "Only branch instructions allowed in loop latches");
2950 
2951     if (BI->isUnconditional())
2952       BackedgeCondition = LatchBBDom;
2953     else {
2954       SmallVector<isl_set *, 8> ConditionSets;
2955       int idx = BI->getSuccessor(0) != HeaderBB;
2956       if (!buildConditionSets(*this, LatchBB, TI, L, LatchBBDom.get(),
2957                               InvalidDomainMap, ConditionSets))
2958         return false;
2959 
2960       // Free the non back edge condition set as we do not need it.
2961       isl_set_free(ConditionSets[1 - idx]);
2962 
2963       BackedgeCondition = isl::manage(ConditionSets[idx]);
2964     }
2965 
2966     int LatchLoopDepth = getRelativeLoopDepth(LI.getLoopFor(LatchBB));
2967     assert(LatchLoopDepth >= LoopDepth);
2968     BackedgeCondition = BackedgeCondition.project_out(
2969         isl::dim::set, LoopDepth + 1, LatchLoopDepth - LoopDepth);
2970     UnionBackedgeCondition = UnionBackedgeCondition.unite(BackedgeCondition);
2971   }
2972 
2973   isl::map ForwardMap = ForwardMap.lex_le(HeaderBBDom.get_space());
2974   for (int i = 0; i < LoopDepth; i++)
2975     ForwardMap = ForwardMap.equate(isl::dim::in, i, isl::dim::out, i);
2976 
2977   isl::set UnionBackedgeConditionComplement =
2978       UnionBackedgeCondition.complement();
2979   UnionBackedgeConditionComplement =
2980       UnionBackedgeConditionComplement.lower_bound_si(isl::dim::set, LoopDepth,
2981                                                       0);
2982   UnionBackedgeConditionComplement =
2983       UnionBackedgeConditionComplement.apply(ForwardMap);
2984   HeaderBBDom = HeaderBBDom.subtract(UnionBackedgeConditionComplement);
2985   HeaderBBDom = HeaderBBDom.apply(NextIterationMap);
2986 
2987   auto Parts = partitionSetParts(HeaderBBDom, LoopDepth);
2988   HeaderBBDom = Parts.second;
2989 
2990   // Check if there is a <nsw> tagged AddRec for this loop and if so do not add
2991   // the bounded assumptions to the context as they are already implied by the
2992   // <nsw> tag.
2993   if (Affinator.hasNSWAddRecForLoop(L))
2994     return true;
2995 
2996   isl::set UnboundedCtx = Parts.first.params();
2997   recordAssumption(INFINITELOOP, UnboundedCtx,
2998                    HeaderBB->getTerminator()->getDebugLoc(), AS_RESTRICTION);
2999   return true;
3000 }
3001 
3002 MemoryAccess *Scop::lookupBasePtrAccess(MemoryAccess *MA) {
3003   Value *PointerBase = MA->getOriginalBaseAddr();
3004 
3005   auto *PointerBaseInst = dyn_cast<Instruction>(PointerBase);
3006   if (!PointerBaseInst)
3007     return nullptr;
3008 
3009   auto *BasePtrStmt = getStmtFor(PointerBaseInst);
3010   if (!BasePtrStmt)
3011     return nullptr;
3012 
3013   return BasePtrStmt->getArrayAccessOrNULLFor(PointerBaseInst);
3014 }
3015 
3016 bool Scop::hasNonHoistableBasePtrInScop(MemoryAccess *MA,
3017                                         isl::union_map Writes) {
3018   if (auto *BasePtrMA = lookupBasePtrAccess(MA)) {
3019     return getNonHoistableCtx(BasePtrMA, Writes).is_null();
3020   }
3021 
3022   Value *BaseAddr = MA->getOriginalBaseAddr();
3023   if (auto *BasePtrInst = dyn_cast<Instruction>(BaseAddr))
3024     if (!isa<LoadInst>(BasePtrInst))
3025       return contains(BasePtrInst);
3026 
3027   return false;
3028 }
3029 
3030 bool Scop::buildAliasChecks(AliasAnalysis &AA) {
3031   if (!PollyUseRuntimeAliasChecks)
3032     return true;
3033 
3034   if (buildAliasGroups(AA)) {
3035     // Aliasing assumptions do not go through addAssumption but we still want to
3036     // collect statistics so we do it here explicitly.
3037     if (MinMaxAliasGroups.size())
3038       AssumptionsAliasing++;
3039     return true;
3040   }
3041 
3042   // If a problem occurs while building the alias groups we need to delete
3043   // this SCoP and pretend it wasn't valid in the first place. To this end
3044   // we make the assumed context infeasible.
3045   invalidate(ALIASING, DebugLoc());
3046 
3047   LLVM_DEBUG(
3048       dbgs() << "\n\nNOTE: Run time checks for " << getNameStr()
3049              << " could not be created as the number of parameters involved "
3050                 "is too high. The SCoP will be "
3051                 "dismissed.\nUse:\n\t--polly-rtc-max-parameters=X\nto adjust "
3052                 "the maximal number of parameters but be advised that the "
3053                 "compile time might increase exponentially.\n\n");
3054   return false;
3055 }
3056 
3057 std::tuple<Scop::AliasGroupVectorTy, DenseSet<const ScopArrayInfo *>>
3058 Scop::buildAliasGroupsForAccesses(AliasAnalysis &AA) {
3059   AliasSetTracker AST(AA);
3060 
3061   DenseMap<Value *, MemoryAccess *> PtrToAcc;
3062   DenseSet<const ScopArrayInfo *> HasWriteAccess;
3063   for (ScopStmt &Stmt : *this) {
3064 
3065     isl::set StmtDomain = Stmt.getDomain();
3066     bool StmtDomainEmpty = StmtDomain.is_empty();
3067 
3068     // Statements with an empty domain will never be executed.
3069     if (StmtDomainEmpty)
3070       continue;
3071 
3072     for (MemoryAccess *MA : Stmt) {
3073       if (MA->isScalarKind())
3074         continue;
3075       if (!MA->isRead())
3076         HasWriteAccess.insert(MA->getScopArrayInfo());
3077       MemAccInst Acc(MA->getAccessInstruction());
3078       if (MA->isRead() && isa<MemTransferInst>(Acc))
3079         PtrToAcc[cast<MemTransferInst>(Acc)->getRawSource()] = MA;
3080       else
3081         PtrToAcc[Acc.getPointerOperand()] = MA;
3082       AST.add(Acc);
3083     }
3084   }
3085 
3086   AliasGroupVectorTy AliasGroups;
3087   for (AliasSet &AS : AST) {
3088     if (AS.isMustAlias() || AS.isForwardingAliasSet())
3089       continue;
3090     AliasGroupTy AG;
3091     for (auto &PR : AS)
3092       AG.push_back(PtrToAcc[PR.getValue()]);
3093     if (AG.size() < 2)
3094       continue;
3095     AliasGroups.push_back(std::move(AG));
3096   }
3097 
3098   return std::make_tuple(AliasGroups, HasWriteAccess);
3099 }
3100 
3101 void Scop::splitAliasGroupsByDomain(AliasGroupVectorTy &AliasGroups) {
3102   for (unsigned u = 0; u < AliasGroups.size(); u++) {
3103     AliasGroupTy NewAG;
3104     AliasGroupTy &AG = AliasGroups[u];
3105     AliasGroupTy::iterator AGI = AG.begin();
3106     isl::set AGDomain = getAccessDomain(*AGI);
3107     while (AGI != AG.end()) {
3108       MemoryAccess *MA = *AGI;
3109       isl::set MADomain = getAccessDomain(MA);
3110       if (AGDomain.is_disjoint(MADomain)) {
3111         NewAG.push_back(MA);
3112         AGI = AG.erase(AGI);
3113       } else {
3114         AGDomain = AGDomain.unite(MADomain);
3115         AGI++;
3116       }
3117     }
3118     if (NewAG.size() > 1)
3119       AliasGroups.push_back(std::move(NewAG));
3120   }
3121 }
3122 
3123 bool Scop::buildAliasGroups(AliasAnalysis &AA) {
3124   // To create sound alias checks we perform the following steps:
3125   //   o) We partition each group into read only and non read only accesses.
3126   //   o) For each group with more than one base pointer we then compute minimal
3127   //      and maximal accesses to each array of a group in read only and non
3128   //      read only partitions separately.
3129   AliasGroupVectorTy AliasGroups;
3130   DenseSet<const ScopArrayInfo *> HasWriteAccess;
3131 
3132   std::tie(AliasGroups, HasWriteAccess) = buildAliasGroupsForAccesses(AA);
3133 
3134   splitAliasGroupsByDomain(AliasGroups);
3135 
3136   for (AliasGroupTy &AG : AliasGroups) {
3137     if (!hasFeasibleRuntimeContext())
3138       return false;
3139 
3140     {
3141       IslMaxOperationsGuard MaxOpGuard(getIslCtx().get(), OptComputeOut);
3142       bool Valid = buildAliasGroup(AG, HasWriteAccess);
3143       if (!Valid)
3144         return false;
3145     }
3146     if (isl_ctx_last_error(getIslCtx().get()) == isl_error_quota) {
3147       invalidate(COMPLEXITY, DebugLoc());
3148       return false;
3149     }
3150   }
3151 
3152   return true;
3153 }
3154 
3155 bool Scop::buildAliasGroup(Scop::AliasGroupTy &AliasGroup,
3156                            DenseSet<const ScopArrayInfo *> HasWriteAccess) {
3157   AliasGroupTy ReadOnlyAccesses;
3158   AliasGroupTy ReadWriteAccesses;
3159   SmallPtrSet<const ScopArrayInfo *, 4> ReadWriteArrays;
3160   SmallPtrSet<const ScopArrayInfo *, 4> ReadOnlyArrays;
3161 
3162   if (AliasGroup.size() < 2)
3163     return true;
3164 
3165   for (MemoryAccess *Access : AliasGroup) {
3166     ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "PossibleAlias",
3167                                         Access->getAccessInstruction())
3168              << "Possibly aliasing pointer, use restrict keyword.");
3169     const ScopArrayInfo *Array = Access->getScopArrayInfo();
3170     if (HasWriteAccess.count(Array)) {
3171       ReadWriteArrays.insert(Array);
3172       ReadWriteAccesses.push_back(Access);
3173     } else {
3174       ReadOnlyArrays.insert(Array);
3175       ReadOnlyAccesses.push_back(Access);
3176     }
3177   }
3178 
3179   // If there are no read-only pointers, and less than two read-write pointers,
3180   // no alias check is needed.
3181   if (ReadOnlyAccesses.empty() && ReadWriteArrays.size() <= 1)
3182     return true;
3183 
3184   // If there is no read-write pointer, no alias check is needed.
3185   if (ReadWriteArrays.empty())
3186     return true;
3187 
3188   // For non-affine accesses, no alias check can be generated as we cannot
3189   // compute a sufficiently tight lower and upper bound: bail out.
3190   for (MemoryAccess *MA : AliasGroup) {
3191     if (!MA->isAffine()) {
3192       invalidate(ALIASING, MA->getAccessInstruction()->getDebugLoc(),
3193                  MA->getAccessInstruction()->getParent());
3194       return false;
3195     }
3196   }
3197 
3198   // Ensure that for all memory accesses for which we generate alias checks,
3199   // their base pointers are available.
3200   for (MemoryAccess *MA : AliasGroup) {
3201     if (MemoryAccess *BasePtrMA = lookupBasePtrAccess(MA))
3202       addRequiredInvariantLoad(
3203           cast<LoadInst>(BasePtrMA->getAccessInstruction()));
3204   }
3205 
3206   MinMaxAliasGroups.emplace_back();
3207   MinMaxVectorPairTy &pair = MinMaxAliasGroups.back();
3208   MinMaxVectorTy &MinMaxAccessesReadWrite = pair.first;
3209   MinMaxVectorTy &MinMaxAccessesReadOnly = pair.second;
3210 
3211   bool Valid;
3212 
3213   Valid =
3214       calculateMinMaxAccess(ReadWriteAccesses, *this, MinMaxAccessesReadWrite);
3215 
3216   if (!Valid)
3217     return false;
3218 
3219   // Bail out if the number of values we need to compare is too large.
3220   // This is important as the number of comparisons grows quadratically with
3221   // the number of values we need to compare.
3222   if (MinMaxAccessesReadWrite.size() + ReadOnlyArrays.size() >
3223       RunTimeChecksMaxArraysPerGroup)
3224     return false;
3225 
3226   Valid =
3227       calculateMinMaxAccess(ReadOnlyAccesses, *this, MinMaxAccessesReadOnly);
3228 
3229   if (!Valid)
3230     return false;
3231 
3232   return true;
3233 }
3234 
3235 /// Get the smallest loop that contains @p S but is not in @p S.
3236 static Loop *getLoopSurroundingScop(Scop &S, LoopInfo &LI) {
3237   // Start with the smallest loop containing the entry and expand that
3238   // loop until it contains all blocks in the region. If there is a loop
3239   // containing all blocks in the region check if it is itself contained
3240   // and if so take the parent loop as it will be the smallest containing
3241   // the region but not contained by it.
3242   Loop *L = LI.getLoopFor(S.getEntry());
3243   while (L) {
3244     bool AllContained = true;
3245     for (auto *BB : S.blocks())
3246       AllContained &= L->contains(BB);
3247     if (AllContained)
3248       break;
3249     L = L->getParentLoop();
3250   }
3251 
3252   return L ? (S.contains(L) ? L->getParentLoop() : L) : nullptr;
3253 }
3254 
3255 int Scop::NextScopID = 0;
3256 
3257 std::string Scop::CurrentFunc;
3258 
3259 int Scop::getNextID(std::string ParentFunc) {
3260   if (ParentFunc != CurrentFunc) {
3261     CurrentFunc = ParentFunc;
3262     NextScopID = 0;
3263   }
3264   return NextScopID++;
3265 }
3266 
3267 Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
3268            DominatorTree &DT, ScopDetection::DetectionContext &DC,
3269            OptimizationRemarkEmitter &ORE)
3270     : IslCtx(isl_ctx_alloc(), isl_ctx_free), SE(&ScalarEvolution), DT(&DT),
3271       R(R), name(None), HasSingleExitEdge(R.getExitingBlock()), DC(DC),
3272       ORE(ORE), Affinator(this, LI),
3273       ID(getNextID((*R.getEntry()->getParent()).getName().str())) {
3274   if (IslOnErrorAbort)
3275     isl_options_set_on_error(getIslCtx().get(), ISL_ON_ERROR_ABORT);
3276   buildContext();
3277 }
3278 
3279 Scop::~Scop() = default;
3280 
3281 void Scop::foldSizeConstantsToRight() {
3282   isl::union_set Accessed = getAccesses().range();
3283 
3284   for (auto Array : arrays()) {
3285     if (Array->getNumberOfDimensions() <= 1)
3286       continue;
3287 
3288     isl::space Space = Array->getSpace();
3289     Space = Space.align_params(Accessed.get_space());
3290 
3291     if (!Accessed.contains(Space))
3292       continue;
3293 
3294     isl::set Elements = Accessed.extract_set(Space);
3295     isl::map Transform = isl::map::universe(Array->getSpace().map_from_set());
3296 
3297     std::vector<int> Int;
3298     int Dims = Elements.dim(isl::dim::set);
3299     for (int i = 0; i < Dims; i++) {
3300       isl::set DimOnly = isl::set(Elements).project_out(isl::dim::set, 0, i);
3301       DimOnly = DimOnly.project_out(isl::dim::set, 1, Dims - i - 1);
3302       DimOnly = DimOnly.lower_bound_si(isl::dim::set, 0, 0);
3303 
3304       isl::basic_set DimHull = DimOnly.affine_hull();
3305 
3306       if (i == Dims - 1) {
3307         Int.push_back(1);
3308         Transform = Transform.equate(isl::dim::in, i, isl::dim::out, i);
3309         continue;
3310       }
3311 
3312       if (DimHull.dim(isl::dim::div) == 1) {
3313         isl::aff Diff = DimHull.get_div(0);
3314         isl::val Val = Diff.get_denominator_val();
3315 
3316         int ValInt = 1;
3317         if (Val.is_int()) {
3318           auto ValAPInt = APIntFromVal(Val);
3319           if (ValAPInt.isSignedIntN(32))
3320             ValInt = ValAPInt.getSExtValue();
3321         } else {
3322         }
3323 
3324         Int.push_back(ValInt);
3325         isl::constraint C = isl::constraint::alloc_equality(
3326             isl::local_space(Transform.get_space()));
3327         C = C.set_coefficient_si(isl::dim::out, i, ValInt);
3328         C = C.set_coefficient_si(isl::dim::in, i, -1);
3329         Transform = Transform.add_constraint(C);
3330         continue;
3331       }
3332 
3333       isl::basic_set ZeroSet = isl::basic_set(DimHull);
3334       ZeroSet = ZeroSet.fix_si(isl::dim::set, 0, 0);
3335 
3336       int ValInt = 1;
3337       if (ZeroSet.is_equal(DimHull)) {
3338         ValInt = 0;
3339       }
3340 
3341       Int.push_back(ValInt);
3342       Transform = Transform.equate(isl::dim::in, i, isl::dim::out, i);
3343     }
3344 
3345     isl::set MappedElements = isl::map(Transform).domain();
3346     if (!Elements.is_subset(MappedElements))
3347       continue;
3348 
3349     bool CanFold = true;
3350     if (Int[0] <= 1)
3351       CanFold = false;
3352 
3353     unsigned NumDims = Array->getNumberOfDimensions();
3354     for (unsigned i = 1; i < NumDims - 1; i++)
3355       if (Int[0] != Int[i] && Int[i])
3356         CanFold = false;
3357 
3358     if (!CanFold)
3359       continue;
3360 
3361     for (auto &Access : AccessFunctions)
3362       if (Access->getScopArrayInfo() == Array)
3363         Access->setAccessRelation(
3364             Access->getAccessRelation().apply_range(Transform));
3365 
3366     std::vector<const SCEV *> Sizes;
3367     for (unsigned i = 0; i < NumDims; i++) {
3368       auto Size = Array->getDimensionSize(i);
3369 
3370       if (i == NumDims - 1)
3371         Size = SE->getMulExpr(Size, SE->getConstant(Size->getType(), Int[0]));
3372       Sizes.push_back(Size);
3373     }
3374 
3375     Array->updateSizes(Sizes, false /* CheckConsistency */);
3376   }
3377 }
3378 
3379 void Scop::markFortranArrays() {
3380   for (ScopStmt &Stmt : Stmts) {
3381     for (MemoryAccess *MemAcc : Stmt) {
3382       Value *FAD = MemAcc->getFortranArrayDescriptor();
3383       if (!FAD)
3384         continue;
3385 
3386       // TODO: const_cast-ing to edit
3387       ScopArrayInfo *SAI =
3388           const_cast<ScopArrayInfo *>(MemAcc->getLatestScopArrayInfo());
3389       assert(SAI && "memory access into a Fortran array does not "
3390                     "have an associated ScopArrayInfo");
3391       SAI->applyAndSetFAD(FAD);
3392     }
3393   }
3394 }
3395 
3396 void Scop::finalizeAccesses() {
3397   updateAccessDimensionality();
3398   foldSizeConstantsToRight();
3399   foldAccessRelations();
3400   assumeNoOutOfBounds();
3401   markFortranArrays();
3402 }
3403 
3404 void Scop::updateAccessDimensionality() {
3405   // Check all array accesses for each base pointer and find a (virtual) element
3406   // size for the base pointer that divides all access functions.
3407   for (ScopStmt &Stmt : *this)
3408     for (MemoryAccess *Access : Stmt) {
3409       if (!Access->isArrayKind())
3410         continue;
3411       ScopArrayInfo *Array =
3412           const_cast<ScopArrayInfo *>(Access->getScopArrayInfo());
3413 
3414       if (Array->getNumberOfDimensions() != 1)
3415         continue;
3416       unsigned DivisibleSize = Array->getElemSizeInBytes();
3417       const SCEV *Subscript = Access->getSubscript(0);
3418       while (!isDivisible(Subscript, DivisibleSize, *SE))
3419         DivisibleSize /= 2;
3420       auto *Ty = IntegerType::get(SE->getContext(), DivisibleSize * 8);
3421       Array->updateElementType(Ty);
3422     }
3423 
3424   for (auto &Stmt : *this)
3425     for (auto &Access : Stmt)
3426       Access->updateDimensionality();
3427 }
3428 
3429 void Scop::foldAccessRelations() {
3430   for (auto &Stmt : *this)
3431     for (auto &Access : Stmt)
3432       Access->foldAccessRelation();
3433 }
3434 
3435 void Scop::assumeNoOutOfBounds() {
3436   for (auto &Stmt : *this)
3437     for (auto &Access : Stmt)
3438       Access->assumeNoOutOfBound();
3439 }
3440 
3441 void Scop::removeFromStmtMap(ScopStmt &Stmt) {
3442   for (Instruction *Inst : Stmt.getInstructions())
3443     InstStmtMap.erase(Inst);
3444 
3445   if (Stmt.isRegionStmt()) {
3446     for (BasicBlock *BB : Stmt.getRegion()->blocks()) {
3447       StmtMap.erase(BB);
3448       // Skip entry basic block, as its instructions are already deleted as
3449       // part of the statement's instruction list.
3450       if (BB == Stmt.getEntryBlock())
3451         continue;
3452       for (Instruction &Inst : *BB)
3453         InstStmtMap.erase(&Inst);
3454     }
3455   } else {
3456     auto StmtMapIt = StmtMap.find(Stmt.getBasicBlock());
3457     if (StmtMapIt != StmtMap.end())
3458       StmtMapIt->second.erase(std::remove(StmtMapIt->second.begin(),
3459                                           StmtMapIt->second.end(), &Stmt),
3460                               StmtMapIt->second.end());
3461     for (Instruction *Inst : Stmt.getInstructions())
3462       InstStmtMap.erase(Inst);
3463   }
3464 }
3465 
3466 void Scop::removeStmts(std::function<bool(ScopStmt &)> ShouldDelete,
3467                        bool AfterHoisting) {
3468   for (auto StmtIt = Stmts.begin(), StmtEnd = Stmts.end(); StmtIt != StmtEnd;) {
3469     if (!ShouldDelete(*StmtIt)) {
3470       StmtIt++;
3471       continue;
3472     }
3473 
3474     // Start with removing all of the statement's accesses including erasing it
3475     // from all maps that are pointing to them.
3476     // Make a temporary copy because removing MAs invalidates the iterator.
3477     SmallVector<MemoryAccess *, 16> MAList(StmtIt->begin(), StmtIt->end());
3478     for (MemoryAccess *MA : MAList)
3479       StmtIt->removeSingleMemoryAccess(MA, AfterHoisting);
3480 
3481     removeFromStmtMap(*StmtIt);
3482     StmtIt = Stmts.erase(StmtIt);
3483   }
3484 }
3485 
3486 void Scop::removeStmtNotInDomainMap() {
3487   auto ShouldDelete = [this](ScopStmt &Stmt) -> bool {
3488     isl::set Domain = DomainMap.lookup(Stmt.getEntryBlock());
3489     if (!Domain)
3490       return true;
3491     return Domain.is_empty();
3492   };
3493   removeStmts(ShouldDelete, false);
3494 }
3495 
3496 void Scop::simplifySCoP(bool AfterHoisting) {
3497   auto ShouldDelete = [AfterHoisting](ScopStmt &Stmt) -> bool {
3498     // Never delete statements that contain calls to debug functions.
3499     if (hasDebugCall(&Stmt))
3500       return false;
3501 
3502     bool RemoveStmt = Stmt.isEmpty();
3503 
3504     // Remove read only statements only after invariant load hoisting.
3505     if (!RemoveStmt && AfterHoisting) {
3506       bool OnlyRead = true;
3507       for (MemoryAccess *MA : Stmt) {
3508         if (MA->isRead())
3509           continue;
3510 
3511         OnlyRead = false;
3512         break;
3513       }
3514 
3515       RemoveStmt = OnlyRead;
3516     }
3517     return RemoveStmt;
3518   };
3519 
3520   removeStmts(ShouldDelete, AfterHoisting);
3521 }
3522 
3523 InvariantEquivClassTy *Scop::lookupInvariantEquivClass(Value *Val) {
3524   LoadInst *LInst = dyn_cast<LoadInst>(Val);
3525   if (!LInst)
3526     return nullptr;
3527 
3528   if (Value *Rep = InvEquivClassVMap.lookup(LInst))
3529     LInst = cast<LoadInst>(Rep);
3530 
3531   Type *Ty = LInst->getType();
3532   const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
3533   for (auto &IAClass : InvariantEquivClasses) {
3534     if (PointerSCEV != IAClass.IdentifyingPointer || Ty != IAClass.AccessType)
3535       continue;
3536 
3537     auto &MAs = IAClass.InvariantAccesses;
3538     for (auto *MA : MAs)
3539       if (MA->getAccessInstruction() == Val)
3540         return &IAClass;
3541   }
3542 
3543   return nullptr;
3544 }
3545 
3546 bool isAParameter(llvm::Value *maybeParam, const Function &F) {
3547   for (const llvm::Argument &Arg : F.args())
3548     if (&Arg == maybeParam)
3549       return true;
3550 
3551   return false;
3552 }
3553 
3554 bool Scop::canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty,
3555                               bool MAInvalidCtxIsEmpty,
3556                               bool NonHoistableCtxIsEmpty) {
3557   LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction());
3558   const DataLayout &DL = LInst->getParent()->getModule()->getDataLayout();
3559   if (PollyAllowDereferenceOfAllFunctionParams &&
3560       isAParameter(LInst->getPointerOperand(), getFunction()))
3561     return true;
3562 
3563   // TODO: We can provide more information for better but more expensive
3564   //       results.
3565   if (!isDereferenceableAndAlignedPointer(LInst->getPointerOperand(),
3566                                           LInst->getAlignment(), DL))
3567     return false;
3568 
3569   // If the location might be overwritten we do not hoist it unconditionally.
3570   //
3571   // TODO: This is probably too conservative.
3572   if (!NonHoistableCtxIsEmpty)
3573     return false;
3574 
3575   // If a dereferenceable load is in a statement that is modeled precisely we
3576   // can hoist it.
3577   if (StmtInvalidCtxIsEmpty && MAInvalidCtxIsEmpty)
3578     return true;
3579 
3580   // Even if the statement is not modeled precisely we can hoist the load if it
3581   // does not involve any parameters that might have been specialized by the
3582   // statement domain.
3583   for (unsigned u = 0, e = MA->getNumSubscripts(); u < e; u++)
3584     if (!isa<SCEVConstant>(MA->getSubscript(u)))
3585       return false;
3586   return true;
3587 }
3588 
3589 void Scop::addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs) {
3590   if (InvMAs.empty())
3591     return;
3592 
3593   isl::set StmtInvalidCtx = Stmt.getInvalidContext();
3594   bool StmtInvalidCtxIsEmpty = StmtInvalidCtx.is_empty();
3595 
3596   // Get the context under which the statement is executed but remove the error
3597   // context under which this statement is reached.
3598   isl::set DomainCtx = Stmt.getDomain().params();
3599   DomainCtx = DomainCtx.subtract(StmtInvalidCtx);
3600 
3601   if (DomainCtx.n_basic_set() >= MaxDisjunctsInDomain) {
3602     auto *AccInst = InvMAs.front().MA->getAccessInstruction();
3603     invalidate(COMPLEXITY, AccInst->getDebugLoc(), AccInst->getParent());
3604     return;
3605   }
3606 
3607   // Project out all parameters that relate to loads in the statement. Otherwise
3608   // we could have cyclic dependences on the constraints under which the
3609   // hoisted loads are executed and we could not determine an order in which to
3610   // pre-load them. This happens because not only lower bounds are part of the
3611   // domain but also upper bounds.
3612   for (auto &InvMA : InvMAs) {
3613     auto *MA = InvMA.MA;
3614     Instruction *AccInst = MA->getAccessInstruction();
3615     if (SE->isSCEVable(AccInst->getType())) {
3616       SetVector<Value *> Values;
3617       for (const SCEV *Parameter : Parameters) {
3618         Values.clear();
3619         findValues(Parameter, *SE, Values);
3620         if (!Values.count(AccInst))
3621           continue;
3622 
3623         if (isl::id ParamId = getIdForParam(Parameter)) {
3624           int Dim = DomainCtx.find_dim_by_id(isl::dim::param, ParamId);
3625           if (Dim >= 0)
3626             DomainCtx = DomainCtx.eliminate(isl::dim::param, Dim, 1);
3627         }
3628       }
3629     }
3630   }
3631 
3632   for (auto &InvMA : InvMAs) {
3633     auto *MA = InvMA.MA;
3634     isl::set NHCtx = InvMA.NonHoistableCtx;
3635 
3636     // Check for another invariant access that accesses the same location as
3637     // MA and if found consolidate them. Otherwise create a new equivalence
3638     // class at the end of InvariantEquivClasses.
3639     LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction());
3640     Type *Ty = LInst->getType();
3641     const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
3642 
3643     isl::set MAInvalidCtx = MA->getInvalidContext();
3644     bool NonHoistableCtxIsEmpty = NHCtx.is_empty();
3645     bool MAInvalidCtxIsEmpty = MAInvalidCtx.is_empty();
3646 
3647     isl::set MACtx;
3648     // Check if we know that this pointer can be speculatively accessed.
3649     if (canAlwaysBeHoisted(MA, StmtInvalidCtxIsEmpty, MAInvalidCtxIsEmpty,
3650                            NonHoistableCtxIsEmpty)) {
3651       MACtx = isl::set::universe(DomainCtx.get_space());
3652     } else {
3653       MACtx = DomainCtx;
3654       MACtx = MACtx.subtract(MAInvalidCtx.unite(NHCtx));
3655       MACtx = MACtx.gist_params(getContext());
3656     }
3657 
3658     bool Consolidated = false;
3659     for (auto &IAClass : InvariantEquivClasses) {
3660       if (PointerSCEV != IAClass.IdentifyingPointer || Ty != IAClass.AccessType)
3661         continue;
3662 
3663       // If the pointer and the type is equal check if the access function wrt.
3664       // to the domain is equal too. It can happen that the domain fixes
3665       // parameter values and these can be different for distinct part of the
3666       // SCoP. If this happens we cannot consolidate the loads but need to
3667       // create a new invariant load equivalence class.
3668       auto &MAs = IAClass.InvariantAccesses;
3669       if (!MAs.empty()) {
3670         auto *LastMA = MAs.front();
3671 
3672         isl::set AR = MA->getAccessRelation().range();
3673         isl::set LastAR = LastMA->getAccessRelation().range();
3674         bool SameAR = AR.is_equal(LastAR);
3675 
3676         if (!SameAR)
3677           continue;
3678       }
3679 
3680       // Add MA to the list of accesses that are in this class.
3681       MAs.push_front(MA);
3682 
3683       Consolidated = true;
3684 
3685       // Unify the execution context of the class and this statement.
3686       isl::set IAClassDomainCtx = IAClass.ExecutionContext;
3687       if (IAClassDomainCtx)
3688         IAClassDomainCtx = IAClassDomainCtx.unite(MACtx).coalesce();
3689       else
3690         IAClassDomainCtx = MACtx;
3691       IAClass.ExecutionContext = IAClassDomainCtx;
3692       break;
3693     }
3694 
3695     if (Consolidated)
3696       continue;
3697 
3698     MACtx = MACtx.coalesce();
3699 
3700     // If we did not consolidate MA, thus did not find an equivalence class
3701     // for it, we create a new one.
3702     InvariantEquivClasses.emplace_back(
3703         InvariantEquivClassTy{PointerSCEV, MemoryAccessList{MA}, MACtx, Ty});
3704   }
3705 }
3706 
3707 /// Check if an access range is too complex.
3708 ///
3709 /// An access range is too complex, if it contains either many disjuncts or
3710 /// very complex expressions. As a simple heuristic, we assume if a set to
3711 /// be too complex if the sum of existentially quantified dimensions and
3712 /// set dimensions is larger than a threshold. This reliably detects both
3713 /// sets with many disjuncts as well as sets with many divisions as they
3714 /// arise in h264.
3715 ///
3716 /// @param AccessRange The range to check for complexity.
3717 ///
3718 /// @returns True if the access range is too complex.
3719 static bool isAccessRangeTooComplex(isl::set AccessRange) {
3720   unsigned NumTotalDims = 0;
3721 
3722   for (isl::basic_set BSet : AccessRange.get_basic_set_list()) {
3723     NumTotalDims += BSet.dim(isl::dim::div);
3724     NumTotalDims += BSet.dim(isl::dim::set);
3725   }
3726 
3727   if (NumTotalDims > MaxDimensionsInAccessRange)
3728     return true;
3729 
3730   return false;
3731 }
3732 
3733 isl::set Scop::getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes) {
3734   // TODO: Loads that are not loop carried, hence are in a statement with
3735   //       zero iterators, are by construction invariant, though we
3736   //       currently "hoist" them anyway. This is necessary because we allow
3737   //       them to be treated as parameters (e.g., in conditions) and our code
3738   //       generation would otherwise use the old value.
3739 
3740   auto &Stmt = *Access->getStatement();
3741   BasicBlock *BB = Stmt.getEntryBlock();
3742 
3743   if (Access->isScalarKind() || Access->isWrite() || !Access->isAffine() ||
3744       Access->isMemoryIntrinsic())
3745     return nullptr;
3746 
3747   // Skip accesses that have an invariant base pointer which is defined but
3748   // not loaded inside the SCoP. This can happened e.g., if a readnone call
3749   // returns a pointer that is used as a base address. However, as we want
3750   // to hoist indirect pointers, we allow the base pointer to be defined in
3751   // the region if it is also a memory access. Each ScopArrayInfo object
3752   // that has a base pointer origin has a base pointer that is loaded and
3753   // that it is invariant, thus it will be hoisted too. However, if there is
3754   // no base pointer origin we check that the base pointer is defined
3755   // outside the region.
3756   auto *LI = cast<LoadInst>(Access->getAccessInstruction());
3757   if (hasNonHoistableBasePtrInScop(Access, Writes))
3758     return nullptr;
3759 
3760   isl::map AccessRelation = Access->getAccessRelation();
3761   assert(!AccessRelation.is_empty());
3762 
3763   if (AccessRelation.involves_dims(isl::dim::in, 0, Stmt.getNumIterators()))
3764     return nullptr;
3765 
3766   AccessRelation = AccessRelation.intersect_domain(Stmt.getDomain());
3767   isl::set SafeToLoad;
3768 
3769   auto &DL = getFunction().getParent()->getDataLayout();
3770   if (isSafeToLoadUnconditionally(LI->getPointerOperand(), LI->getAlignment(),
3771                                   DL)) {
3772     SafeToLoad = isl::set::universe(AccessRelation.get_space().range());
3773   } else if (BB != LI->getParent()) {
3774     // Skip accesses in non-affine subregions as they might not be executed
3775     // under the same condition as the entry of the non-affine subregion.
3776     return nullptr;
3777   } else {
3778     SafeToLoad = AccessRelation.range();
3779   }
3780 
3781   if (isAccessRangeTooComplex(AccessRelation.range()))
3782     return nullptr;
3783 
3784   isl::union_map Written = Writes.intersect_range(SafeToLoad);
3785   isl::set WrittenCtx = Written.params();
3786   bool IsWritten = !WrittenCtx.is_empty();
3787 
3788   if (!IsWritten)
3789     return WrittenCtx;
3790 
3791   WrittenCtx = WrittenCtx.remove_divs();
3792   bool TooComplex = WrittenCtx.n_basic_set() >= MaxDisjunctsInDomain;
3793   if (TooComplex || !isRequiredInvariantLoad(LI))
3794     return nullptr;
3795 
3796   addAssumption(INVARIANTLOAD, WrittenCtx, LI->getDebugLoc(), AS_RESTRICTION,
3797                 LI->getParent());
3798   return WrittenCtx;
3799 }
3800 
3801 void Scop::verifyInvariantLoads() {
3802   auto &RIL = getRequiredInvariantLoads();
3803   for (LoadInst *LI : RIL) {
3804     assert(LI && contains(LI));
3805     // If there exists a statement in the scop which has a memory access for
3806     // @p LI, then mark this scop as infeasible for optimization.
3807     for (ScopStmt &Stmt : Stmts)
3808       if (Stmt.getArrayAccessOrNULLFor(LI)) {
3809         invalidate(INVARIANTLOAD, LI->getDebugLoc(), LI->getParent());
3810         return;
3811       }
3812   }
3813 }
3814 
3815 void Scop::hoistInvariantLoads() {
3816   if (!PollyInvariantLoadHoisting)
3817     return;
3818 
3819   isl::union_map Writes = getWrites();
3820   for (ScopStmt &Stmt : *this) {
3821     InvariantAccessesTy InvariantAccesses;
3822 
3823     for (MemoryAccess *Access : Stmt)
3824       if (isl::set NHCtx = getNonHoistableCtx(Access, Writes))
3825         InvariantAccesses.push_back({Access, NHCtx});
3826 
3827     // Transfer the memory access from the statement to the SCoP.
3828     for (auto InvMA : InvariantAccesses)
3829       Stmt.removeMemoryAccess(InvMA.MA);
3830     addInvariantLoads(Stmt, InvariantAccesses);
3831   }
3832 }
3833 
3834 /// Find the canonical scop array info object for a set of invariant load
3835 /// hoisted loads. The canonical array is the one that corresponds to the
3836 /// first load in the list of accesses which is used as base pointer of a
3837 /// scop array.
3838 static const ScopArrayInfo *findCanonicalArray(Scop *S,
3839                                                MemoryAccessList &Accesses) {
3840   for (MemoryAccess *Access : Accesses) {
3841     const ScopArrayInfo *CanonicalArray = S->getScopArrayInfoOrNull(
3842         Access->getAccessInstruction(), MemoryKind::Array);
3843     if (CanonicalArray)
3844       return CanonicalArray;
3845   }
3846   return nullptr;
3847 }
3848 
3849 /// Check if @p Array severs as base array in an invariant load.
3850 static bool isUsedForIndirectHoistedLoad(Scop *S, const ScopArrayInfo *Array) {
3851   for (InvariantEquivClassTy &EqClass2 : S->getInvariantAccesses())
3852     for (MemoryAccess *Access2 : EqClass2.InvariantAccesses)
3853       if (Access2->getScopArrayInfo() == Array)
3854         return true;
3855   return false;
3856 }
3857 
3858 /// Replace the base pointer arrays in all memory accesses referencing @p Old,
3859 /// with a reference to @p New.
3860 static void replaceBasePtrArrays(Scop *S, const ScopArrayInfo *Old,
3861                                  const ScopArrayInfo *New) {
3862   for (ScopStmt &Stmt : *S)
3863     for (MemoryAccess *Access : Stmt) {
3864       if (Access->getLatestScopArrayInfo() != Old)
3865         continue;
3866 
3867       isl::id Id = New->getBasePtrId();
3868       isl::map Map = Access->getAccessRelation();
3869       Map = Map.set_tuple_id(isl::dim::out, Id);
3870       Access->setAccessRelation(Map);
3871     }
3872 }
3873 
3874 void Scop::canonicalizeDynamicBasePtrs() {
3875   for (InvariantEquivClassTy &EqClass : InvariantEquivClasses) {
3876     MemoryAccessList &BasePtrAccesses = EqClass.InvariantAccesses;
3877 
3878     const ScopArrayInfo *CanonicalBasePtrSAI =
3879         findCanonicalArray(this, BasePtrAccesses);
3880 
3881     if (!CanonicalBasePtrSAI)
3882       continue;
3883 
3884     for (MemoryAccess *BasePtrAccess : BasePtrAccesses) {
3885       const ScopArrayInfo *BasePtrSAI = getScopArrayInfoOrNull(
3886           BasePtrAccess->getAccessInstruction(), MemoryKind::Array);
3887       if (!BasePtrSAI || BasePtrSAI == CanonicalBasePtrSAI ||
3888           !BasePtrSAI->isCompatibleWith(CanonicalBasePtrSAI))
3889         continue;
3890 
3891       // we currently do not canonicalize arrays where some accesses are
3892       // hoisted as invariant loads. If we would, we need to update the access
3893       // function of the invariant loads as well. However, as this is not a
3894       // very common situation, we leave this for now to avoid further
3895       // complexity increases.
3896       if (isUsedForIndirectHoistedLoad(this, BasePtrSAI))
3897         continue;
3898 
3899       replaceBasePtrArrays(this, BasePtrSAI, CanonicalBasePtrSAI);
3900     }
3901   }
3902 }
3903 
3904 ScopArrayInfo *Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType,
3905                                               ArrayRef<const SCEV *> Sizes,
3906                                               MemoryKind Kind,
3907                                               const char *BaseName) {
3908   assert((BasePtr || BaseName) &&
3909          "BasePtr and BaseName can not be nullptr at the same time.");
3910   assert(!(BasePtr && BaseName) && "BaseName is redundant.");
3911   auto &SAI = BasePtr ? ScopArrayInfoMap[std::make_pair(BasePtr, Kind)]
3912                       : ScopArrayNameMap[BaseName];
3913   if (!SAI) {
3914     auto &DL = getFunction().getParent()->getDataLayout();
3915     SAI.reset(new ScopArrayInfo(BasePtr, ElementType, getIslCtx(), Sizes, Kind,
3916                                 DL, this, BaseName));
3917     ScopArrayInfoSet.insert(SAI.get());
3918   } else {
3919     SAI->updateElementType(ElementType);
3920     // In case of mismatching array sizes, we bail out by setting the run-time
3921     // context to false.
3922     if (!SAI->updateSizes(Sizes))
3923       invalidate(DELINEARIZATION, DebugLoc());
3924   }
3925   return SAI.get();
3926 }
3927 
3928 ScopArrayInfo *Scop::createScopArrayInfo(Type *ElementType,
3929                                          const std::string &BaseName,
3930                                          const std::vector<unsigned> &Sizes) {
3931   auto *DimSizeType = Type::getInt64Ty(getSE()->getContext());
3932   std::vector<const SCEV *> SCEVSizes;
3933 
3934   for (auto size : Sizes)
3935     if (size)
3936       SCEVSizes.push_back(getSE()->getConstant(DimSizeType, size, false));
3937     else
3938       SCEVSizes.push_back(nullptr);
3939 
3940   auto *SAI = getOrCreateScopArrayInfo(nullptr, ElementType, SCEVSizes,
3941                                        MemoryKind::Array, BaseName.c_str());
3942   return SAI;
3943 }
3944 
3945 const ScopArrayInfo *Scop::getScopArrayInfoOrNull(Value *BasePtr,
3946                                                   MemoryKind Kind) {
3947   auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)].get();
3948   return SAI;
3949 }
3950 
3951 const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr, MemoryKind Kind) {
3952   auto *SAI = getScopArrayInfoOrNull(BasePtr, Kind);
3953   assert(SAI && "No ScopArrayInfo available for this base pointer");
3954   return SAI;
3955 }
3956 
3957 std::string Scop::getContextStr() const { return getContext().to_str(); }
3958 
3959 std::string Scop::getAssumedContextStr() const {
3960   assert(AssumedContext && "Assumed context not yet built");
3961   return AssumedContext.to_str();
3962 }
3963 
3964 std::string Scop::getInvalidContextStr() const {
3965   return InvalidContext.to_str();
3966 }
3967 
3968 std::string Scop::getNameStr() const {
3969   std::string ExitName, EntryName;
3970   std::tie(EntryName, ExitName) = getEntryExitStr();
3971   return EntryName + "---" + ExitName;
3972 }
3973 
3974 std::pair<std::string, std::string> Scop::getEntryExitStr() const {
3975   std::string ExitName, EntryName;
3976   raw_string_ostream ExitStr(ExitName);
3977   raw_string_ostream EntryStr(EntryName);
3978 
3979   R.getEntry()->printAsOperand(EntryStr, false);
3980   EntryStr.str();
3981 
3982   if (R.getExit()) {
3983     R.getExit()->printAsOperand(ExitStr, false);
3984     ExitStr.str();
3985   } else
3986     ExitName = "FunctionExit";
3987 
3988   return std::make_pair(EntryName, ExitName);
3989 }
3990 
3991 isl::set Scop::getContext() const { return Context; }
3992 isl::space Scop::getParamSpace() const { return getContext().get_space(); }
3993 
3994 isl::space Scop::getFullParamSpace() const {
3995   std::vector<isl::id> FortranIDs;
3996   FortranIDs = getFortranArrayIds(arrays());
3997 
3998   isl::space Space = isl::space::params_alloc(
3999       getIslCtx(), ParameterIds.size() + FortranIDs.size());
4000 
4001   unsigned PDim = 0;
4002   for (const SCEV *Parameter : Parameters) {
4003     isl::id Id = getIdForParam(Parameter);
4004     Space = Space.set_dim_id(isl::dim::param, PDim++, Id);
4005   }
4006 
4007   for (isl::id Id : FortranIDs)
4008     Space = Space.set_dim_id(isl::dim::param, PDim++, Id);
4009 
4010   return Space;
4011 }
4012 
4013 isl::set Scop::getAssumedContext() const {
4014   assert(AssumedContext && "Assumed context not yet built");
4015   return AssumedContext;
4016 }
4017 
4018 bool Scop::isProfitable(bool ScalarsAreUnprofitable) const {
4019   if (PollyProcessUnprofitable)
4020     return true;
4021 
4022   if (isEmpty())
4023     return false;
4024 
4025   unsigned OptimizableStmtsOrLoops = 0;
4026   for (auto &Stmt : *this) {
4027     if (Stmt.getNumIterators() == 0)
4028       continue;
4029 
4030     bool ContainsArrayAccs = false;
4031     bool ContainsScalarAccs = false;
4032     for (auto *MA : Stmt) {
4033       if (MA->isRead())
4034         continue;
4035       ContainsArrayAccs |= MA->isLatestArrayKind();
4036       ContainsScalarAccs |= MA->isLatestScalarKind();
4037     }
4038 
4039     if (!ScalarsAreUnprofitable || (ContainsArrayAccs && !ContainsScalarAccs))
4040       OptimizableStmtsOrLoops += Stmt.getNumIterators();
4041   }
4042 
4043   return OptimizableStmtsOrLoops > 1;
4044 }
4045 
4046 bool Scop::hasFeasibleRuntimeContext() const {
4047   auto PositiveContext = getAssumedContext();
4048   auto NegativeContext = getInvalidContext();
4049   PositiveContext = addNonEmptyDomainConstraints(PositiveContext);
4050   // addNonEmptyDomainConstraints returns null if ScopStmts have a null domain
4051   if (!PositiveContext)
4052     return false;
4053 
4054   bool IsFeasible = !(PositiveContext.is_empty() ||
4055                       PositiveContext.is_subset(NegativeContext));
4056   if (!IsFeasible)
4057     return false;
4058 
4059   auto DomainContext = getDomains().params();
4060   IsFeasible = !DomainContext.is_subset(NegativeContext);
4061   IsFeasible &= !Context.is_subset(NegativeContext);
4062 
4063   return IsFeasible;
4064 }
4065 
4066 static std::string toString(AssumptionKind Kind) {
4067   switch (Kind) {
4068   case ALIASING:
4069     return "No-aliasing";
4070   case INBOUNDS:
4071     return "Inbounds";
4072   case WRAPPING:
4073     return "No-overflows";
4074   case UNSIGNED:
4075     return "Signed-unsigned";
4076   case COMPLEXITY:
4077     return "Low complexity";
4078   case PROFITABLE:
4079     return "Profitable";
4080   case ERRORBLOCK:
4081     return "No-error";
4082   case INFINITELOOP:
4083     return "Finite loop";
4084   case INVARIANTLOAD:
4085     return "Invariant load";
4086   case DELINEARIZATION:
4087     return "Delinearization";
4088   }
4089   llvm_unreachable("Unknown AssumptionKind!");
4090 }
4091 
4092 bool Scop::isEffectiveAssumption(isl::set Set, AssumptionSign Sign) {
4093   if (Sign == AS_ASSUMPTION) {
4094     if (Context.is_subset(Set))
4095       return false;
4096 
4097     if (AssumedContext.is_subset(Set))
4098       return false;
4099   } else {
4100     if (Set.is_disjoint(Context))
4101       return false;
4102 
4103     if (Set.is_subset(InvalidContext))
4104       return false;
4105   }
4106   return true;
4107 }
4108 
4109 bool Scop::trackAssumption(AssumptionKind Kind, isl::set Set, DebugLoc Loc,
4110                            AssumptionSign Sign, BasicBlock *BB) {
4111   if (PollyRemarksMinimal && !isEffectiveAssumption(Set, Sign))
4112     return false;
4113 
4114   // Do never emit trivial assumptions as they only clutter the output.
4115   if (!PollyRemarksMinimal) {
4116     isl::set Univ;
4117     if (Sign == AS_ASSUMPTION)
4118       Univ = isl::set::universe(Set.get_space());
4119 
4120     bool IsTrivial = (Sign == AS_RESTRICTION && Set.is_empty()) ||
4121                      (Sign == AS_ASSUMPTION && Univ.is_equal(Set));
4122 
4123     if (IsTrivial)
4124       return false;
4125   }
4126 
4127   switch (Kind) {
4128   case ALIASING:
4129     AssumptionsAliasing++;
4130     break;
4131   case INBOUNDS:
4132     AssumptionsInbounds++;
4133     break;
4134   case WRAPPING:
4135     AssumptionsWrapping++;
4136     break;
4137   case UNSIGNED:
4138     AssumptionsUnsigned++;
4139     break;
4140   case COMPLEXITY:
4141     AssumptionsComplexity++;
4142     break;
4143   case PROFITABLE:
4144     AssumptionsUnprofitable++;
4145     break;
4146   case ERRORBLOCK:
4147     AssumptionsErrorBlock++;
4148     break;
4149   case INFINITELOOP:
4150     AssumptionsInfiniteLoop++;
4151     break;
4152   case INVARIANTLOAD:
4153     AssumptionsInvariantLoad++;
4154     break;
4155   case DELINEARIZATION:
4156     AssumptionsDelinearization++;
4157     break;
4158   }
4159 
4160   auto Suffix = Sign == AS_ASSUMPTION ? " assumption:\t" : " restriction:\t";
4161   std::string Msg = toString(Kind) + Suffix + Set.to_str();
4162   if (BB)
4163     ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AssumpRestrict", Loc, BB)
4164              << Msg);
4165   else
4166     ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AssumpRestrict", Loc,
4167                                         R.getEntry())
4168              << Msg);
4169   return true;
4170 }
4171 
4172 void Scop::addAssumption(AssumptionKind Kind, isl::set Set, DebugLoc Loc,
4173                          AssumptionSign Sign, BasicBlock *BB) {
4174   // Simplify the assumptions/restrictions first.
4175   Set = Set.gist_params(getContext());
4176 
4177   if (!trackAssumption(Kind, Set, Loc, Sign, BB))
4178     return;
4179 
4180   if (Sign == AS_ASSUMPTION)
4181     AssumedContext = AssumedContext.intersect(Set).coalesce();
4182   else
4183     InvalidContext = InvalidContext.unite(Set).coalesce();
4184 }
4185 
4186 void Scop::recordAssumption(AssumptionKind Kind, isl::set Set, DebugLoc Loc,
4187                             AssumptionSign Sign, BasicBlock *BB) {
4188   assert((Set.is_params() || BB) &&
4189          "Assumptions without a basic block must be parameter sets");
4190   RecordedAssumptions.push_back({Kind, Sign, Set, Loc, BB});
4191 }
4192 
4193 void Scop::addRecordedAssumptions() {
4194   while (!RecordedAssumptions.empty()) {
4195     Assumption AS = RecordedAssumptions.pop_back_val();
4196 
4197     if (!AS.BB) {
4198       addAssumption(AS.Kind, AS.Set, AS.Loc, AS.Sign, nullptr /* BasicBlock */);
4199       continue;
4200     }
4201 
4202     // If the domain was deleted the assumptions are void.
4203     isl_set *Dom = getDomainConditions(AS.BB).release();
4204     if (!Dom)
4205       continue;
4206 
4207     // If a basic block was given use its domain to simplify the assumption.
4208     // In case of restrictions we know they only have to hold on the domain,
4209     // thus we can intersect them with the domain of the block. However, for
4210     // assumptions the domain has to imply them, thus:
4211     //                     _              _____
4212     //   Dom => S   <==>   A v B   <==>   A - B
4213     //
4214     // To avoid the complement we will register A - B as a restriction not an
4215     // assumption.
4216     isl_set *S = AS.Set.copy();
4217     if (AS.Sign == AS_RESTRICTION)
4218       S = isl_set_params(isl_set_intersect(S, Dom));
4219     else /* (AS.Sign == AS_ASSUMPTION) */
4220       S = isl_set_params(isl_set_subtract(Dom, S));
4221 
4222     addAssumption(AS.Kind, isl::manage(S), AS.Loc, AS_RESTRICTION, AS.BB);
4223   }
4224 }
4225 
4226 void Scop::invalidate(AssumptionKind Kind, DebugLoc Loc, BasicBlock *BB) {
4227   LLVM_DEBUG(dbgs() << "Invalidate SCoP because of reason " << Kind << "\n");
4228   addAssumption(Kind, isl::set::empty(getParamSpace()), Loc, AS_ASSUMPTION, BB);
4229 }
4230 
4231 isl::set Scop::getInvalidContext() const { return InvalidContext; }
4232 
4233 void Scop::printContext(raw_ostream &OS) const {
4234   OS << "Context:\n";
4235   OS.indent(4) << Context << "\n";
4236 
4237   OS.indent(4) << "Assumed Context:\n";
4238   OS.indent(4) << AssumedContext << "\n";
4239 
4240   OS.indent(4) << "Invalid Context:\n";
4241   OS.indent(4) << InvalidContext << "\n";
4242 
4243   unsigned Dim = 0;
4244   for (const SCEV *Parameter : Parameters)
4245     OS.indent(4) << "p" << Dim++ << ": " << *Parameter << "\n";
4246 }
4247 
4248 void Scop::printAliasAssumptions(raw_ostream &OS) const {
4249   int noOfGroups = 0;
4250   for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
4251     if (Pair.second.size() == 0)
4252       noOfGroups += 1;
4253     else
4254       noOfGroups += Pair.second.size();
4255   }
4256 
4257   OS.indent(4) << "Alias Groups (" << noOfGroups << "):\n";
4258   if (MinMaxAliasGroups.empty()) {
4259     OS.indent(8) << "n/a\n";
4260     return;
4261   }
4262 
4263   for (const MinMaxVectorPairTy &Pair : MinMaxAliasGroups) {
4264 
4265     // If the group has no read only accesses print the write accesses.
4266     if (Pair.second.empty()) {
4267       OS.indent(8) << "[[";
4268       for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
4269         OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
4270            << ">";
4271       }
4272       OS << " ]]\n";
4273     }
4274 
4275     for (const MinMaxAccessTy &MMAReadOnly : Pair.second) {
4276       OS.indent(8) << "[[";
4277       OS << " <" << MMAReadOnly.first << ", " << MMAReadOnly.second << ">";
4278       for (const MinMaxAccessTy &MMANonReadOnly : Pair.first) {
4279         OS << " <" << MMANonReadOnly.first << ", " << MMANonReadOnly.second
4280            << ">";
4281       }
4282       OS << " ]]\n";
4283     }
4284   }
4285 }
4286 
4287 void Scop::printStatements(raw_ostream &OS, bool PrintInstructions) const {
4288   OS << "Statements {\n";
4289 
4290   for (const ScopStmt &Stmt : *this) {
4291     OS.indent(4);
4292     Stmt.print(OS, PrintInstructions);
4293   }
4294 
4295   OS.indent(4) << "}\n";
4296 }
4297 
4298 void Scop::printArrayInfo(raw_ostream &OS) const {
4299   OS << "Arrays {\n";
4300 
4301   for (auto &Array : arrays())
4302     Array->print(OS);
4303 
4304   OS.indent(4) << "}\n";
4305 
4306   OS.indent(4) << "Arrays (Bounds as pw_affs) {\n";
4307 
4308   for (auto &Array : arrays())
4309     Array->print(OS, /* SizeAsPwAff */ true);
4310 
4311   OS.indent(4) << "}\n";
4312 }
4313 
4314 void Scop::print(raw_ostream &OS, bool PrintInstructions) const {
4315   OS.indent(4) << "Function: " << getFunction().getName() << "\n";
4316   OS.indent(4) << "Region: " << getNameStr() << "\n";
4317   OS.indent(4) << "Max Loop Depth:  " << getMaxLoopDepth() << "\n";
4318   OS.indent(4) << "Invariant Accesses: {\n";
4319   for (const auto &IAClass : InvariantEquivClasses) {
4320     const auto &MAs = IAClass.InvariantAccesses;
4321     if (MAs.empty()) {
4322       OS.indent(12) << "Class Pointer: " << *IAClass.IdentifyingPointer << "\n";
4323     } else {
4324       MAs.front()->print(OS);
4325       OS.indent(12) << "Execution Context: " << IAClass.ExecutionContext
4326                     << "\n";
4327     }
4328   }
4329   OS.indent(4) << "}\n";
4330   printContext(OS.indent(4));
4331   printArrayInfo(OS.indent(4));
4332   printAliasAssumptions(OS);
4333   printStatements(OS.indent(4), PrintInstructions);
4334 }
4335 
4336 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4337 LLVM_DUMP_METHOD void Scop::dump() const { print(dbgs(), true); }
4338 #endif
4339 
4340 isl::ctx Scop::getIslCtx() const { return IslCtx.get(); }
4341 
4342 __isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB,
4343                                  bool NonNegative) {
4344   // First try to use the SCEVAffinator to generate a piecewise defined
4345   // affine function from @p E in the context of @p BB. If that tasks becomes to
4346   // complex the affinator might return a nullptr. In such a case we invalidate
4347   // the SCoP and return a dummy value. This way we do not need to add error
4348   // handling code to all users of this function.
4349   auto PWAC = Affinator.getPwAff(E, BB);
4350   if (PWAC.first) {
4351     // TODO: We could use a heuristic and either use:
4352     //         SCEVAffinator::takeNonNegativeAssumption
4353     //       or
4354     //         SCEVAffinator::interpretAsUnsigned
4355     //       to deal with unsigned or "NonNegative" SCEVs.
4356     if (NonNegative)
4357       Affinator.takeNonNegativeAssumption(PWAC);
4358     return PWAC;
4359   }
4360 
4361   auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
4362   invalidate(COMPLEXITY, DL, BB);
4363   return Affinator.getPwAff(SE->getZero(E->getType()), BB);
4364 }
4365 
4366 isl::union_set Scop::getDomains() const {
4367   isl_space *EmptySpace = isl_space_params_alloc(getIslCtx().get(), 0);
4368   isl_union_set *Domain = isl_union_set_empty(EmptySpace);
4369 
4370   for (const ScopStmt &Stmt : *this)
4371     Domain = isl_union_set_add_set(Domain, Stmt.getDomain().release());
4372 
4373   return isl::manage(Domain);
4374 }
4375 
4376 isl::pw_aff Scop::getPwAffOnly(const SCEV *E, BasicBlock *BB) {
4377   PWACtx PWAC = getPwAff(E, BB);
4378   return PWAC.first;
4379 }
4380 
4381 isl::union_map
4382 Scop::getAccessesOfType(std::function<bool(MemoryAccess &)> Predicate) {
4383   isl::union_map Accesses = isl::union_map::empty(getParamSpace());
4384 
4385   for (ScopStmt &Stmt : *this) {
4386     for (MemoryAccess *MA : Stmt) {
4387       if (!Predicate(*MA))
4388         continue;
4389 
4390       isl::set Domain = Stmt.getDomain();
4391       isl::map AccessDomain = MA->getAccessRelation();
4392       AccessDomain = AccessDomain.intersect_domain(Domain);
4393       Accesses = Accesses.add_map(AccessDomain);
4394     }
4395   }
4396 
4397   return Accesses.coalesce();
4398 }
4399 
4400 isl::union_map Scop::getMustWrites() {
4401   return getAccessesOfType([](MemoryAccess &MA) { return MA.isMustWrite(); });
4402 }
4403 
4404 isl::union_map Scop::getMayWrites() {
4405   return getAccessesOfType([](MemoryAccess &MA) { return MA.isMayWrite(); });
4406 }
4407 
4408 isl::union_map Scop::getWrites() {
4409   return getAccessesOfType([](MemoryAccess &MA) { return MA.isWrite(); });
4410 }
4411 
4412 isl::union_map Scop::getReads() {
4413   return getAccessesOfType([](MemoryAccess &MA) { return MA.isRead(); });
4414 }
4415 
4416 isl::union_map Scop::getAccesses() {
4417   return getAccessesOfType([](MemoryAccess &MA) { return true; });
4418 }
4419 
4420 isl::union_map Scop::getAccesses(ScopArrayInfo *Array) {
4421   return getAccessesOfType(
4422       [Array](MemoryAccess &MA) { return MA.getScopArrayInfo() == Array; });
4423 }
4424 
4425 // Check whether @p Node is an extension node.
4426 //
4427 // @return true if @p Node is an extension node.
4428 isl_bool isNotExtNode(__isl_keep isl_schedule_node *Node, void *User) {
4429   if (isl_schedule_node_get_type(Node) == isl_schedule_node_extension)
4430     return isl_bool_error;
4431   else
4432     return isl_bool_true;
4433 }
4434 
4435 bool Scop::containsExtensionNode(isl::schedule Schedule) {
4436   return isl_schedule_foreach_schedule_node_top_down(
4437              Schedule.get(), isNotExtNode, nullptr) == isl_stat_error;
4438 }
4439 
4440 isl::union_map Scop::getSchedule() const {
4441   auto Tree = getScheduleTree();
4442   if (containsExtensionNode(Tree))
4443     return nullptr;
4444 
4445   return Tree.get_map();
4446 }
4447 
4448 isl::schedule Scop::getScheduleTree() const {
4449   return Schedule.intersect_domain(getDomains());
4450 }
4451 
4452 void Scop::setSchedule(isl::union_map NewSchedule) {
4453   auto S = isl::schedule::from_domain(getDomains());
4454   Schedule = S.insert_partial_schedule(
4455       isl::multi_union_pw_aff::from_union_map(NewSchedule));
4456   ScheduleModified = true;
4457 }
4458 
4459 void Scop::setScheduleTree(isl::schedule NewSchedule) {
4460   Schedule = NewSchedule;
4461   ScheduleModified = true;
4462 }
4463 
4464 bool Scop::restrictDomains(isl::union_set Domain) {
4465   bool Changed = false;
4466   for (ScopStmt &Stmt : *this) {
4467     isl::union_set StmtDomain = isl::union_set(Stmt.getDomain());
4468     isl::union_set NewStmtDomain = StmtDomain.intersect(Domain);
4469 
4470     if (StmtDomain.is_subset(NewStmtDomain))
4471       continue;
4472 
4473     Changed = true;
4474 
4475     NewStmtDomain = NewStmtDomain.coalesce();
4476 
4477     if (NewStmtDomain.is_empty())
4478       Stmt.restrictDomain(isl::set::empty(Stmt.getDomainSpace()));
4479     else
4480       Stmt.restrictDomain(isl::set(NewStmtDomain));
4481   }
4482   return Changed;
4483 }
4484 
4485 ScalarEvolution *Scop::getSE() const { return SE; }
4486 
4487 // Create an isl_multi_union_aff that defines an identity mapping from the
4488 // elements of USet to their N-th dimension.
4489 //
4490 // # Example:
4491 //
4492 //            Domain: { A[i,j]; B[i,j,k] }
4493 //                 N: 1
4494 //
4495 // Resulting Mapping: { {A[i,j] -> [(j)]; B[i,j,k] -> [(j)] }
4496 //
4497 // @param USet   A union set describing the elements for which to generate a
4498 //               mapping.
4499 // @param N      The dimension to map to.
4500 // @returns      A mapping from USet to its N-th dimension.
4501 static isl::multi_union_pw_aff mapToDimension(isl::union_set USet, int N) {
4502   assert(N >= 0);
4503   assert(USet);
4504   assert(!USet.is_empty());
4505 
4506   auto Result = isl::union_pw_multi_aff::empty(USet.get_space());
4507 
4508   for (isl::set S : USet.get_set_list()) {
4509     int Dim = S.dim(isl::dim::set);
4510     auto PMA = isl::pw_multi_aff::project_out_map(S.get_space(), isl::dim::set,
4511                                                   N, Dim - N);
4512     if (N > 1)
4513       PMA = PMA.drop_dims(isl::dim::out, 0, N - 1);
4514 
4515     Result = Result.add_pw_multi_aff(PMA);
4516   }
4517 
4518   return isl::multi_union_pw_aff(isl::union_pw_multi_aff(Result));
4519 }
4520 
4521 void Scop::addScopStmt(BasicBlock *BB, StringRef Name, Loop *SurroundingLoop,
4522                        std::vector<Instruction *> Instructions) {
4523   assert(BB && "Unexpected nullptr!");
4524   Stmts.emplace_back(*this, *BB, Name, SurroundingLoop, Instructions);
4525   auto *Stmt = &Stmts.back();
4526   StmtMap[BB].push_back(Stmt);
4527   for (Instruction *Inst : Instructions) {
4528     assert(!InstStmtMap.count(Inst) &&
4529            "Unexpected statement corresponding to the instruction.");
4530     InstStmtMap[Inst] = Stmt;
4531   }
4532 }
4533 
4534 void Scop::addScopStmt(Region *R, StringRef Name, Loop *SurroundingLoop,
4535                        std::vector<Instruction *> Instructions) {
4536   assert(R && "Unexpected nullptr!");
4537   Stmts.emplace_back(*this, *R, Name, SurroundingLoop, Instructions);
4538   auto *Stmt = &Stmts.back();
4539 
4540   for (Instruction *Inst : Instructions) {
4541     assert(!InstStmtMap.count(Inst) &&
4542            "Unexpected statement corresponding to the instruction.");
4543     InstStmtMap[Inst] = Stmt;
4544   }
4545 
4546   for (BasicBlock *BB : R->blocks()) {
4547     StmtMap[BB].push_back(Stmt);
4548     if (BB == R->getEntry())
4549       continue;
4550     for (Instruction &Inst : *BB) {
4551       assert(!InstStmtMap.count(&Inst) &&
4552              "Unexpected statement corresponding to the instruction.");
4553       InstStmtMap[&Inst] = Stmt;
4554     }
4555   }
4556 }
4557 
4558 ScopStmt *Scop::addScopStmt(isl::map SourceRel, isl::map TargetRel,
4559                             isl::set Domain) {
4560 #ifndef NDEBUG
4561   isl::set SourceDomain = SourceRel.domain();
4562   isl::set TargetDomain = TargetRel.domain();
4563   assert(Domain.is_subset(TargetDomain) &&
4564          "Target access not defined for complete statement domain");
4565   assert(Domain.is_subset(SourceDomain) &&
4566          "Source access not defined for complete statement domain");
4567 #endif
4568   Stmts.emplace_back(*this, SourceRel, TargetRel, Domain);
4569   CopyStmtsNum++;
4570   return &(Stmts.back());
4571 }
4572 
4573 void Scop::buildSchedule(LoopInfo &LI) {
4574   Loop *L = getLoopSurroundingScop(*this, LI);
4575   LoopStackTy LoopStack({LoopStackElementTy(L, nullptr, 0)});
4576   buildSchedule(getRegion().getNode(), LoopStack, LI);
4577   assert(LoopStack.size() == 1 && LoopStack.back().L == L);
4578   Schedule = LoopStack[0].Schedule;
4579 }
4580 
4581 /// To generate a schedule for the elements in a Region we traverse the Region
4582 /// in reverse-post-order and add the contained RegionNodes in traversal order
4583 /// to the schedule of the loop that is currently at the top of the LoopStack.
4584 /// For loop-free codes, this results in a correct sequential ordering.
4585 ///
4586 /// Example:
4587 ///           bb1(0)
4588 ///         /     \.
4589 ///      bb2(1)   bb3(2)
4590 ///         \    /  \.
4591 ///          bb4(3)  bb5(4)
4592 ///             \   /
4593 ///              bb6(5)
4594 ///
4595 /// Including loops requires additional processing. Whenever a loop header is
4596 /// encountered, the corresponding loop is added to the @p LoopStack. Starting
4597 /// from an empty schedule, we first process all RegionNodes that are within
4598 /// this loop and complete the sequential schedule at this loop-level before
4599 /// processing about any other nodes. To implement this
4600 /// loop-nodes-first-processing, the reverse post-order traversal is
4601 /// insufficient. Hence, we additionally check if the traversal yields
4602 /// sub-regions or blocks that are outside the last loop on the @p LoopStack.
4603 /// These region-nodes are then queue and only traverse after the all nodes
4604 /// within the current loop have been processed.
4605 void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack, LoopInfo &LI) {
4606   Loop *OuterScopLoop = getLoopSurroundingScop(*this, LI);
4607 
4608   ReversePostOrderTraversal<Region *> RTraversal(R);
4609   std::deque<RegionNode *> WorkList(RTraversal.begin(), RTraversal.end());
4610   std::deque<RegionNode *> DelayList;
4611   bool LastRNWaiting = false;
4612 
4613   // Iterate over the region @p R in reverse post-order but queue
4614   // sub-regions/blocks iff they are not part of the last encountered but not
4615   // completely traversed loop. The variable LastRNWaiting is a flag to indicate
4616   // that we queued the last sub-region/block from the reverse post-order
4617   // iterator. If it is set we have to explore the next sub-region/block from
4618   // the iterator (if any) to guarantee progress. If it is not set we first try
4619   // the next queued sub-region/blocks.
4620   while (!WorkList.empty() || !DelayList.empty()) {
4621     RegionNode *RN;
4622 
4623     if ((LastRNWaiting && !WorkList.empty()) || DelayList.empty()) {
4624       RN = WorkList.front();
4625       WorkList.pop_front();
4626       LastRNWaiting = false;
4627     } else {
4628       RN = DelayList.front();
4629       DelayList.pop_front();
4630     }
4631 
4632     Loop *L = getRegionNodeLoop(RN, LI);
4633     if (!contains(L))
4634       L = OuterScopLoop;
4635 
4636     Loop *LastLoop = LoopStack.back().L;
4637     if (LastLoop != L) {
4638       if (LastLoop && !LastLoop->contains(L)) {
4639         LastRNWaiting = true;
4640         DelayList.push_back(RN);
4641         continue;
4642       }
4643       LoopStack.push_back({L, nullptr, 0});
4644     }
4645     buildSchedule(RN, LoopStack, LI);
4646   }
4647 }
4648 
4649 void Scop::buildSchedule(RegionNode *RN, LoopStackTy &LoopStack, LoopInfo &LI) {
4650   if (RN->isSubRegion()) {
4651     auto *LocalRegion = RN->getNodeAs<Region>();
4652     if (!isNonAffineSubRegion(LocalRegion)) {
4653       buildSchedule(LocalRegion, LoopStack, LI);
4654       return;
4655     }
4656   }
4657 
4658   assert(LoopStack.rbegin() != LoopStack.rend());
4659   auto LoopData = LoopStack.rbegin();
4660   LoopData->NumBlocksProcessed += getNumBlocksInRegionNode(RN);
4661 
4662   for (auto *Stmt : getStmtListFor(RN)) {
4663     isl::union_set UDomain{Stmt->getDomain()};
4664     auto StmtSchedule = isl::schedule::from_domain(UDomain);
4665     LoopData->Schedule = combineInSequence(LoopData->Schedule, StmtSchedule);
4666   }
4667 
4668   // Check if we just processed the last node in this loop. If we did, finalize
4669   // the loop by:
4670   //
4671   //   - adding new schedule dimensions
4672   //   - folding the resulting schedule into the parent loop schedule
4673   //   - dropping the loop schedule from the LoopStack.
4674   //
4675   // Then continue to check surrounding loops, which might also have been
4676   // completed by this node.
4677   size_t Dimension = LoopStack.size();
4678   while (LoopData->L &&
4679          LoopData->NumBlocksProcessed == getNumBlocksInLoop(LoopData->L)) {
4680     isl::schedule Schedule = LoopData->Schedule;
4681     auto NumBlocksProcessed = LoopData->NumBlocksProcessed;
4682 
4683     assert(std::next(LoopData) != LoopStack.rend());
4684     ++LoopData;
4685     --Dimension;
4686 
4687     if (Schedule) {
4688       isl::union_set Domain = Schedule.get_domain();
4689       isl::multi_union_pw_aff MUPA = mapToDimension(Domain, Dimension);
4690       Schedule = Schedule.insert_partial_schedule(MUPA);
4691       LoopData->Schedule = combineInSequence(LoopData->Schedule, Schedule);
4692     }
4693 
4694     LoopData->NumBlocksProcessed += NumBlocksProcessed;
4695   }
4696   // Now pop all loops processed up there from the LoopStack
4697   LoopStack.erase(LoopStack.begin() + Dimension, LoopStack.end());
4698 }
4699 
4700 ArrayRef<ScopStmt *> Scop::getStmtListFor(BasicBlock *BB) const {
4701   auto StmtMapIt = StmtMap.find(BB);
4702   if (StmtMapIt == StmtMap.end())
4703     return {};
4704   return StmtMapIt->second;
4705 }
4706 
4707 ScopStmt *Scop::getIncomingStmtFor(const Use &U) const {
4708   auto *PHI = cast<PHINode>(U.getUser());
4709   BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
4710 
4711   // If the value is a non-synthesizable from the incoming block, use the
4712   // statement that contains it as user statement.
4713   if (auto *IncomingInst = dyn_cast<Instruction>(U.get())) {
4714     if (IncomingInst->getParent() == IncomingBB) {
4715       if (ScopStmt *IncomingStmt = getStmtFor(IncomingInst))
4716         return IncomingStmt;
4717     }
4718   }
4719 
4720   // Otherwise, use the epilogue/last statement.
4721   return getLastStmtFor(IncomingBB);
4722 }
4723 
4724 ScopStmt *Scop::getLastStmtFor(BasicBlock *BB) const {
4725   ArrayRef<ScopStmt *> StmtList = getStmtListFor(BB);
4726   if (!StmtList.empty())
4727     return StmtList.back();
4728   return nullptr;
4729 }
4730 
4731 ArrayRef<ScopStmt *> Scop::getStmtListFor(RegionNode *RN) const {
4732   if (RN->isSubRegion())
4733     return getStmtListFor(RN->getNodeAs<Region>());
4734   return getStmtListFor(RN->getNodeAs<BasicBlock>());
4735 }
4736 
4737 ArrayRef<ScopStmt *> Scop::getStmtListFor(Region *R) const {
4738   return getStmtListFor(R->getEntry());
4739 }
4740 
4741 int Scop::getRelativeLoopDepth(const Loop *L) const {
4742   if (!L || !R.contains(L))
4743     return -1;
4744   // outermostLoopInRegion always returns nullptr for top level regions
4745   if (R.isTopLevelRegion()) {
4746     // LoopInfo's depths start at 1, we start at 0
4747     return L->getLoopDepth() - 1;
4748   } else {
4749     Loop *OuterLoop = R.outermostLoopInRegion(const_cast<Loop *>(L));
4750     assert(OuterLoop);
4751     return L->getLoopDepth() - OuterLoop->getLoopDepth();
4752   }
4753 }
4754 
4755 ScopArrayInfo *Scop::getArrayInfoByName(const std::string BaseName) {
4756   for (auto &SAI : arrays()) {
4757     if (SAI->getName() == BaseName)
4758       return SAI;
4759   }
4760   return nullptr;
4761 }
4762 
4763 void Scop::addAccessData(MemoryAccess *Access) {
4764   const ScopArrayInfo *SAI = Access->getOriginalScopArrayInfo();
4765   assert(SAI && "can only use after access relations have been constructed");
4766 
4767   if (Access->isOriginalValueKind() && Access->isRead())
4768     ValueUseAccs[SAI].push_back(Access);
4769   else if (Access->isOriginalAnyPHIKind() && Access->isWrite())
4770     PHIIncomingAccs[SAI].push_back(Access);
4771 }
4772 
4773 void Scop::removeAccessData(MemoryAccess *Access) {
4774   if (Access->isOriginalValueKind() && Access->isWrite()) {
4775     ValueDefAccs.erase(Access->getAccessValue());
4776   } else if (Access->isOriginalValueKind() && Access->isRead()) {
4777     auto &Uses = ValueUseAccs[Access->getScopArrayInfo()];
4778     auto NewEnd = std::remove(Uses.begin(), Uses.end(), Access);
4779     Uses.erase(NewEnd, Uses.end());
4780   } else if (Access->isOriginalPHIKind() && Access->isRead()) {
4781     PHINode *PHI = cast<PHINode>(Access->getAccessInstruction());
4782     PHIReadAccs.erase(PHI);
4783   } else if (Access->isOriginalAnyPHIKind() && Access->isWrite()) {
4784     auto &Incomings = PHIIncomingAccs[Access->getScopArrayInfo()];
4785     auto NewEnd = std::remove(Incomings.begin(), Incomings.end(), Access);
4786     Incomings.erase(NewEnd, Incomings.end());
4787   }
4788 }
4789 
4790 MemoryAccess *Scop::getValueDef(const ScopArrayInfo *SAI) const {
4791   assert(SAI->isValueKind());
4792 
4793   Instruction *Val = dyn_cast<Instruction>(SAI->getBasePtr());
4794   if (!Val)
4795     return nullptr;
4796 
4797   return ValueDefAccs.lookup(Val);
4798 }
4799 
4800 ArrayRef<MemoryAccess *> Scop::getValueUses(const ScopArrayInfo *SAI) const {
4801   assert(SAI->isValueKind());
4802   auto It = ValueUseAccs.find(SAI);
4803   if (It == ValueUseAccs.end())
4804     return {};
4805   return It->second;
4806 }
4807 
4808 MemoryAccess *Scop::getPHIRead(const ScopArrayInfo *SAI) const {
4809   assert(SAI->isPHIKind() || SAI->isExitPHIKind());
4810 
4811   if (SAI->isExitPHIKind())
4812     return nullptr;
4813 
4814   PHINode *PHI = cast<PHINode>(SAI->getBasePtr());
4815   return PHIReadAccs.lookup(PHI);
4816 }
4817 
4818 ArrayRef<MemoryAccess *> Scop::getPHIIncomings(const ScopArrayInfo *SAI) const {
4819   assert(SAI->isPHIKind() || SAI->isExitPHIKind());
4820   auto It = PHIIncomingAccs.find(SAI);
4821   if (It == PHIIncomingAccs.end())
4822     return {};
4823   return It->second;
4824 }
4825 
4826 bool Scop::isEscaping(Instruction *Inst) {
4827   assert(contains(Inst) && "The concept of escaping makes only sense for "
4828                            "values defined inside the SCoP");
4829 
4830   for (Use &Use : Inst->uses()) {
4831     BasicBlock *UserBB = getUseBlock(Use);
4832     if (!contains(UserBB))
4833       return true;
4834 
4835     // When the SCoP region exit needs to be simplified, PHIs in the region exit
4836     // move to a new basic block such that its incoming blocks are not in the
4837     // SCoP anymore.
4838     if (hasSingleExitEdge() && isa<PHINode>(Use.getUser()) &&
4839         isExit(cast<PHINode>(Use.getUser())->getParent()))
4840       return true;
4841   }
4842   return false;
4843 }
4844 
4845 Scop::ScopStatistics Scop::getStatistics() const {
4846   ScopStatistics Result;
4847 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
4848   auto LoopStat = ScopDetection::countBeneficialLoops(&R, *SE, *getLI(), 0);
4849 
4850   int NumTotalLoops = LoopStat.NumLoops;
4851   Result.NumBoxedLoops = getBoxedLoops().size();
4852   Result.NumAffineLoops = NumTotalLoops - Result.NumBoxedLoops;
4853 
4854   for (const ScopStmt &Stmt : *this) {
4855     isl::set Domain = Stmt.getDomain().intersect_params(getContext());
4856     bool IsInLoop = Stmt.getNumIterators() >= 1;
4857     for (MemoryAccess *MA : Stmt) {
4858       if (!MA->isWrite())
4859         continue;
4860 
4861       if (MA->isLatestValueKind()) {
4862         Result.NumValueWrites += 1;
4863         if (IsInLoop)
4864           Result.NumValueWritesInLoops += 1;
4865       }
4866 
4867       if (MA->isLatestAnyPHIKind()) {
4868         Result.NumPHIWrites += 1;
4869         if (IsInLoop)
4870           Result.NumPHIWritesInLoops += 1;
4871       }
4872 
4873       isl::set AccSet =
4874           MA->getAccessRelation().intersect_domain(Domain).range();
4875       if (AccSet.is_singleton()) {
4876         Result.NumSingletonWrites += 1;
4877         if (IsInLoop)
4878           Result.NumSingletonWritesInLoops += 1;
4879       }
4880     }
4881   }
4882 #endif
4883   return Result;
4884 }
4885 
4886 raw_ostream &polly::operator<<(raw_ostream &OS, const Scop &scop) {
4887   scop.print(OS, PollyPrintInstructions);
4888   return OS;
4889 }
4890 
4891 //===----------------------------------------------------------------------===//
4892 void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const {
4893   AU.addRequired<LoopInfoWrapperPass>();
4894   AU.addRequired<RegionInfoPass>();
4895   AU.addRequired<DominatorTreeWrapperPass>();
4896   AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
4897   AU.addRequiredTransitive<ScopDetectionWrapperPass>();
4898   AU.addRequired<AAResultsWrapperPass>();
4899   AU.addRequired<AssumptionCacheTracker>();
4900   AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
4901   AU.setPreservesAll();
4902 }
4903 
4904 void updateLoopCountStatistic(ScopDetection::LoopStats Stats,
4905                               Scop::ScopStatistics ScopStats) {
4906   assert(Stats.NumLoops == ScopStats.NumAffineLoops + ScopStats.NumBoxedLoops);
4907 
4908   NumScops++;
4909   NumLoopsInScop += Stats.NumLoops;
4910   MaxNumLoopsInScop =
4911       std::max(MaxNumLoopsInScop.getValue(), (unsigned)Stats.NumLoops);
4912 
4913   if (Stats.MaxDepth == 0)
4914     NumScopsDepthZero++;
4915   else if (Stats.MaxDepth == 1)
4916     NumScopsDepthOne++;
4917   else if (Stats.MaxDepth == 2)
4918     NumScopsDepthTwo++;
4919   else if (Stats.MaxDepth == 3)
4920     NumScopsDepthThree++;
4921   else if (Stats.MaxDepth == 4)
4922     NumScopsDepthFour++;
4923   else if (Stats.MaxDepth == 5)
4924     NumScopsDepthFive++;
4925   else
4926     NumScopsDepthLarger++;
4927 
4928   NumAffineLoops += ScopStats.NumAffineLoops;
4929   NumBoxedLoops += ScopStats.NumBoxedLoops;
4930 
4931   NumValueWrites += ScopStats.NumValueWrites;
4932   NumValueWritesInLoops += ScopStats.NumValueWritesInLoops;
4933   NumPHIWrites += ScopStats.NumPHIWrites;
4934   NumPHIWritesInLoops += ScopStats.NumPHIWritesInLoops;
4935   NumSingletonWrites += ScopStats.NumSingletonWrites;
4936   NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;
4937 }
4938 
4939 bool ScopInfoRegionPass::runOnRegion(Region *R, RGPassManager &RGM) {
4940   auto &SD = getAnalysis<ScopDetectionWrapperPass>().getSD();
4941 
4942   if (!SD.isMaxRegionInScop(*R))
4943     return false;
4944 
4945   Function *F = R->getEntry()->getParent();
4946   auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
4947   auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
4948   auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
4949   auto const &DL = F->getParent()->getDataLayout();
4950   auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
4951   auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*F);
4952   auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
4953 
4954   ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE, ORE);
4955   S = SB.getScop(); // take ownership of scop object
4956 
4957 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
4958   if (S) {
4959     ScopDetection::LoopStats Stats =
4960         ScopDetection::countBeneficialLoops(&S->getRegion(), SE, LI, 0);
4961     updateLoopCountStatistic(Stats, S->getStatistics());
4962   }
4963 #endif
4964 
4965   return false;
4966 }
4967 
4968 void ScopInfoRegionPass::print(raw_ostream &OS, const Module *) const {
4969   if (S)
4970     S->print(OS, PollyPrintInstructions);
4971   else
4972     OS << "Invalid Scop!\n";
4973 }
4974 
4975 char ScopInfoRegionPass::ID = 0;
4976 
4977 Pass *polly::createScopInfoRegionPassPass() { return new ScopInfoRegionPass(); }
4978 
4979 INITIALIZE_PASS_BEGIN(ScopInfoRegionPass, "polly-scops",
4980                       "Polly - Create polyhedral description of Scops", false,
4981                       false);
4982 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
4983 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker);
4984 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
4985 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
4986 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
4987 INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
4988 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
4989 INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops",
4990                     "Polly - Create polyhedral description of Scops", false,
4991                     false)
4992 
4993 //===----------------------------------------------------------------------===//
4994 ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE,
4995                    LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT,
4996                    AssumptionCache &AC, OptimizationRemarkEmitter &ORE)
4997     : DL(DL), SD(SD), SE(SE), LI(LI), AA(AA), DT(DT), AC(AC), ORE(ORE) {
4998   recompute();
4999 }
5000 
5001 void ScopInfo::recompute() {
5002   RegionToScopMap.clear();
5003   /// Create polyhedral description of scops for all the valid regions of a
5004   /// function.
5005   for (auto &It : SD) {
5006     Region *R = const_cast<Region *>(It);
5007     if (!SD.isMaxRegionInScop(*R))
5008       continue;
5009 
5010     ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE, ORE);
5011     std::unique_ptr<Scop> S = SB.getScop();
5012     if (!S)
5013       continue;
5014 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
5015     ScopDetection::LoopStats Stats =
5016         ScopDetection::countBeneficialLoops(&S->getRegion(), SE, LI, 0);
5017     updateLoopCountStatistic(Stats, S->getStatistics());
5018 #endif
5019     bool Inserted = RegionToScopMap.insert({R, std::move(S)}).second;
5020     assert(Inserted && "Building Scop for the same region twice!");
5021     (void)Inserted;
5022   }
5023 }
5024 
5025 bool ScopInfo::invalidate(Function &F, const PreservedAnalyses &PA,
5026                           FunctionAnalysisManager::Invalidator &Inv) {
5027   // Check whether the analysis, all analyses on functions have been preserved
5028   // or anything we're holding references to is being invalidated
5029   auto PAC = PA.getChecker<ScopInfoAnalysis>();
5030   return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
5031          Inv.invalidate<ScopAnalysis>(F, PA) ||
5032          Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
5033          Inv.invalidate<LoopAnalysis>(F, PA) ||
5034          Inv.invalidate<AAManager>(F, PA) ||
5035          Inv.invalidate<DominatorTreeAnalysis>(F, PA) ||
5036          Inv.invalidate<AssumptionAnalysis>(F, PA);
5037 }
5038 
5039 AnalysisKey ScopInfoAnalysis::Key;
5040 
5041 ScopInfoAnalysis::Result ScopInfoAnalysis::run(Function &F,
5042                                                FunctionAnalysisManager &FAM) {
5043   auto &SD = FAM.getResult<ScopAnalysis>(F);
5044   auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
5045   auto &LI = FAM.getResult<LoopAnalysis>(F);
5046   auto &AA = FAM.getResult<AAManager>(F);
5047   auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
5048   auto &AC = FAM.getResult<AssumptionAnalysis>(F);
5049   auto &DL = F.getParent()->getDataLayout();
5050   auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
5051   return {DL, SD, SE, LI, AA, DT, AC, ORE};
5052 }
5053 
5054 PreservedAnalyses ScopInfoPrinterPass::run(Function &F,
5055                                            FunctionAnalysisManager &FAM) {
5056   auto &SI = FAM.getResult<ScopInfoAnalysis>(F);
5057   // Since the legacy PM processes Scops in bottom up, we print them in reverse
5058   // order here to keep the output persistent
5059   for (auto &It : reverse(SI)) {
5060     if (It.second)
5061       It.second->print(Stream, PollyPrintInstructions);
5062     else
5063       Stream << "Invalid Scop!\n";
5064   }
5065   return PreservedAnalyses::all();
5066 }
5067 
5068 void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
5069   AU.addRequired<LoopInfoWrapperPass>();
5070   AU.addRequired<RegionInfoPass>();
5071   AU.addRequired<DominatorTreeWrapperPass>();
5072   AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
5073   AU.addRequiredTransitive<ScopDetectionWrapperPass>();
5074   AU.addRequired<AAResultsWrapperPass>();
5075   AU.addRequired<AssumptionCacheTracker>();
5076   AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
5077   AU.setPreservesAll();
5078 }
5079 
5080 bool ScopInfoWrapperPass::runOnFunction(Function &F) {
5081   auto &SD = getAnalysis<ScopDetectionWrapperPass>().getSD();
5082   auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
5083   auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
5084   auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
5085   auto const &DL = F.getParent()->getDataLayout();
5086   auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
5087   auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
5088   auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
5089 
5090   Result.reset(new ScopInfo{DL, SD, SE, LI, AA, DT, AC, ORE});
5091   return false;
5092 }
5093 
5094 void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const {
5095   for (auto &It : *Result) {
5096     if (It.second)
5097       It.second->print(OS, PollyPrintInstructions);
5098     else
5099       OS << "Invalid Scop!\n";
5100   }
5101 }
5102 
5103 char ScopInfoWrapperPass::ID = 0;
5104 
5105 Pass *polly::createScopInfoWrapperPassPass() {
5106   return new ScopInfoWrapperPass();
5107 }
5108 
5109 INITIALIZE_PASS_BEGIN(
5110     ScopInfoWrapperPass, "polly-function-scops",
5111     "Polly - Create polyhedral description of all Scops of a function", false,
5112     false);
5113 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
5114 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker);
5115 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
5116 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
5117 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
5118 INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
5119 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
5120 INITIALIZE_PASS_END(
5121     ScopInfoWrapperPass, "polly-function-scops",
5122     "Polly - Create polyhedral description of all Scops of a function", false,
5123     false)
5124