1 //===--------- ScopInfo.cpp  - Create Scops from LLVM IR ------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Create a polyhedral description for a static control flow region.
11 //
12 // The pass creates a polyhedral description of the Scops detected by the Scop
13 // detection derived from their LLVM-IR code.
14 //
15 // This represantation is shared among several tools in the polyhedral
16 // community, which are e.g. Cloog, Pluto, Loopo, Graphite.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #include "polly/CodeGen/BlockGenerators.h"
21 #include "polly/LinkAllPasses.h"
22 #include "polly/ScopInfo.h"
23 #include "polly/Options.h"
24 #include "polly/Support/GICHelper.h"
25 #include "polly/Support/SCEVValidator.h"
26 #include "polly/Support/ScopHelper.h"
27 #include "polly/TempScopInfo.h"
28 #include "llvm/ADT/SetVector.h"
29 #include "llvm/ADT/Statistic.h"
30 #include "llvm/ADT/StringExtras.h"
31 #include "llvm/Analysis/LoopInfo.h"
32 #include "llvm/Analysis/RegionIterator.h"
33 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
34 #include "llvm/Support/Debug.h"
35 
36 #include "isl/constraint.h"
37 #include "isl/set.h"
38 #include "isl/map.h"
39 #include "isl/union_map.h"
40 #include "isl/aff.h"
41 #include "isl/printer.h"
42 #include "isl/local_space.h"
43 #include "isl/options.h"
44 #include "isl/val.h"
45 
46 #include <sstream>
47 #include <string>
48 #include <vector>
49 
50 using namespace llvm;
51 using namespace polly;
52 
53 #define DEBUG_TYPE "polly-scops"
54 
55 STATISTIC(ScopFound, "Number of valid Scops");
56 STATISTIC(RichScopFound, "Number of Scops containing a loop");
57 
58 // Multiplicative reductions can be disabled seperately as these kind of
59 // operations can overflow easily. Additive reductions and bit operations
60 // are in contrast pretty stable.
61 static cl::opt<bool> DisableMultiplicativeReductions(
62     "polly-disable-multiplicative-reductions",
63     cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore,
64     cl::init(false), cl::cat(PollyCategory));
65 
66 /// Translate a 'const SCEV *' expression in an isl_pw_aff.
67 struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
68 public:
69   /// @brief Translate a 'const SCEV *' to an isl_pw_aff.
70   ///
71   /// @param Stmt The location at which the scalar evolution expression
72   ///             is evaluated.
73   /// @param Expr The expression that is translated.
74   static __isl_give isl_pw_aff *getPwAff(ScopStmt *Stmt, const SCEV *Expr);
75 
76 private:
77   isl_ctx *Ctx;
78   int NbLoopSpaces;
79   const Scop *S;
80 
81   SCEVAffinator(const ScopStmt *Stmt);
82   int getLoopDepth(const Loop *L);
83 
84   __isl_give isl_pw_aff *visit(const SCEV *Expr);
85   __isl_give isl_pw_aff *visitConstant(const SCEVConstant *Expr);
86   __isl_give isl_pw_aff *visitTruncateExpr(const SCEVTruncateExpr *Expr);
87   __isl_give isl_pw_aff *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr);
88   __isl_give isl_pw_aff *visitSignExtendExpr(const SCEVSignExtendExpr *Expr);
89   __isl_give isl_pw_aff *visitAddExpr(const SCEVAddExpr *Expr);
90   __isl_give isl_pw_aff *visitMulExpr(const SCEVMulExpr *Expr);
91   __isl_give isl_pw_aff *visitUDivExpr(const SCEVUDivExpr *Expr);
92   __isl_give isl_pw_aff *visitAddRecExpr(const SCEVAddRecExpr *Expr);
93   __isl_give isl_pw_aff *visitSMaxExpr(const SCEVSMaxExpr *Expr);
94   __isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr);
95   __isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr);
96 
97   friend struct SCEVVisitor<SCEVAffinator, isl_pw_aff *>;
98 };
99 
100 SCEVAffinator::SCEVAffinator(const ScopStmt *Stmt)
101     : Ctx(Stmt->getIslCtx()), NbLoopSpaces(Stmt->getNumIterators()),
102       S(Stmt->getParent()) {}
103 
104 __isl_give isl_pw_aff *SCEVAffinator::getPwAff(ScopStmt *Stmt,
105                                                const SCEV *Scev) {
106   Scop *S = Stmt->getParent();
107   const Region *Reg = &S->getRegion();
108 
109   S->addParams(getParamsInAffineExpr(Reg, Scev, *S->getSE()));
110 
111   SCEVAffinator Affinator(Stmt);
112   return Affinator.visit(Scev);
113 }
114 
115 __isl_give isl_pw_aff *SCEVAffinator::visit(const SCEV *Expr) {
116   // In case the scev is a valid parameter, we do not further analyze this
117   // expression, but create a new parameter in the isl_pw_aff. This allows us
118   // to treat subexpressions that we cannot translate into an piecewise affine
119   // expression, as constant parameters of the piecewise affine expression.
120   if (isl_id *Id = S->getIdForParam(Expr)) {
121     isl_space *Space = isl_space_set_alloc(Ctx, 1, NbLoopSpaces);
122     Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
123 
124     isl_set *Domain = isl_set_universe(isl_space_copy(Space));
125     isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space));
126     Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
127 
128     return isl_pw_aff_alloc(Domain, Affine);
129   }
130 
131   return SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Expr);
132 }
133 
134 __isl_give isl_pw_aff *SCEVAffinator::visitConstant(const SCEVConstant *Expr) {
135   ConstantInt *Value = Expr->getValue();
136   isl_val *v;
137 
138   // LLVM does not define if an integer value is interpreted as a signed or
139   // unsigned value. Hence, without further information, it is unknown how
140   // this value needs to be converted to GMP. At the moment, we only support
141   // signed operations. So we just interpret it as signed. Later, there are
142   // two options:
143   //
144   // 1. We always interpret any value as signed and convert the values on
145   //    demand.
146   // 2. We pass down the signedness of the calculation and use it to interpret
147   //    this constant correctly.
148   v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
149 
150   isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
151   isl_local_space *ls = isl_local_space_from_space(isl_space_copy(Space));
152   isl_aff *Affine = isl_aff_zero_on_domain(ls);
153   isl_set *Domain = isl_set_universe(Space);
154 
155   Affine = isl_aff_add_constant_val(Affine, v);
156 
157   return isl_pw_aff_alloc(Domain, Affine);
158 }
159 
160 __isl_give isl_pw_aff *
161 SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
162   llvm_unreachable("SCEVTruncateExpr not yet supported");
163 }
164 
165 __isl_give isl_pw_aff *
166 SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
167   llvm_unreachable("SCEVZeroExtendExpr not yet supported");
168 }
169 
170 __isl_give isl_pw_aff *
171 SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
172   // Assuming the value is signed, a sign extension is basically a noop.
173   // TODO: Reconsider this as soon as we support unsigned values.
174   return visit(Expr->getOperand());
175 }
176 
177 __isl_give isl_pw_aff *SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
178   isl_pw_aff *Sum = visit(Expr->getOperand(0));
179 
180   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
181     isl_pw_aff *NextSummand = visit(Expr->getOperand(i));
182     Sum = isl_pw_aff_add(Sum, NextSummand);
183   }
184 
185   // TODO: Check for NSW and NUW.
186 
187   return Sum;
188 }
189 
190 __isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) {
191   isl_pw_aff *Product = visit(Expr->getOperand(0));
192 
193   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
194     isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
195 
196     if (!isl_pw_aff_is_cst(Product) && !isl_pw_aff_is_cst(NextOperand)) {
197       isl_pw_aff_free(Product);
198       isl_pw_aff_free(NextOperand);
199       return nullptr;
200     }
201 
202     Product = isl_pw_aff_mul(Product, NextOperand);
203   }
204 
205   // TODO: Check for NSW and NUW.
206   return Product;
207 }
208 
209 __isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) {
210   llvm_unreachable("SCEVUDivExpr not yet supported");
211 }
212 
213 __isl_give isl_pw_aff *
214 SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
215   assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
216 
217   // Directly generate isl_pw_aff for Expr if 'start' is zero.
218   if (Expr->getStart()->isZero()) {
219     assert(S->getRegion().contains(Expr->getLoop()) &&
220            "Scop does not contain the loop referenced in this AddRec");
221 
222     isl_pw_aff *Start = visit(Expr->getStart());
223     isl_pw_aff *Step = visit(Expr->getOperand(1));
224     isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
225     isl_local_space *LocalSpace = isl_local_space_from_space(Space);
226 
227     int loopDimension = getLoopDepth(Expr->getLoop());
228 
229     isl_aff *LAff = isl_aff_set_coefficient_si(
230         isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
231     isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
232 
233     // TODO: Do we need to check for NSW and NUW?
234     return isl_pw_aff_add(Start, isl_pw_aff_mul(Step, LPwAff));
235   }
236 
237   // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
238   // if 'start' is not zero.
239   ScalarEvolution &SE = *S->getSE();
240   const SCEV *ZeroStartExpr = SE.getAddRecExpr(
241       SE.getConstant(Expr->getStart()->getType(), 0),
242       Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
243 
244   isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr);
245   isl_pw_aff *Start = visit(Expr->getStart());
246 
247   return isl_pw_aff_add(ZeroStartResult, Start);
248 }
249 
250 __isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) {
251   isl_pw_aff *Max = visit(Expr->getOperand(0));
252 
253   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
254     isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
255     Max = isl_pw_aff_max(Max, NextOperand);
256   }
257 
258   return Max;
259 }
260 
261 __isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) {
262   llvm_unreachable("SCEVUMaxExpr not yet supported");
263 }
264 
265 __isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) {
266   llvm_unreachable("Unknowns are always parameters");
267 }
268 
269 int SCEVAffinator::getLoopDepth(const Loop *L) {
270   Loop *outerLoop = S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L));
271   assert(outerLoop && "Scop does not contain this loop");
272   return L->getLoopDepth() - outerLoop->getLoopDepth();
273 }
274 
275 const std::string
276 MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
277   switch (RT) {
278   case MemoryAccess::RT_NONE:
279     llvm_unreachable("Requested a reduction operator string for a memory "
280                      "access which isn't a reduction");
281   case MemoryAccess::RT_ADD:
282     return "+";
283   case MemoryAccess::RT_MUL:
284     return "*";
285   case MemoryAccess::RT_BOR:
286     return "|";
287   case MemoryAccess::RT_BXOR:
288     return "^";
289   case MemoryAccess::RT_BAND:
290     return "&";
291   }
292   llvm_unreachable("Unknown reduction type");
293   return "";
294 }
295 
296 /// @brief Return the reduction type for a given binary operator
297 static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp,
298                                                     const Instruction *Load) {
299   if (!BinOp)
300     return MemoryAccess::RT_NONE;
301   switch (BinOp->getOpcode()) {
302   case Instruction::FAdd:
303     if (!BinOp->hasUnsafeAlgebra())
304       return MemoryAccess::RT_NONE;
305   // Fall through
306   case Instruction::Add:
307     return MemoryAccess::RT_ADD;
308   case Instruction::Or:
309     return MemoryAccess::RT_BOR;
310   case Instruction::Xor:
311     return MemoryAccess::RT_BXOR;
312   case Instruction::And:
313     return MemoryAccess::RT_BAND;
314   case Instruction::FMul:
315     if (!BinOp->hasUnsafeAlgebra())
316       return MemoryAccess::RT_NONE;
317   // Fall through
318   case Instruction::Mul:
319     if (DisableMultiplicativeReductions)
320       return MemoryAccess::RT_NONE;
321     return MemoryAccess::RT_MUL;
322   default:
323     return MemoryAccess::RT_NONE;
324   }
325 }
326 //===----------------------------------------------------------------------===//
327 
328 MemoryAccess::~MemoryAccess() {
329   isl_map_free(AccessRelation);
330   isl_map_free(newAccessRelation);
331 }
332 
333 isl_id *MemoryAccess::getArrayId() const {
334   return isl_map_get_tuple_id(AccessRelation, isl_dim_out);
335 }
336 
337 isl_map *MemoryAccess::getAccessRelation() const {
338   return isl_map_copy(AccessRelation);
339 }
340 
341 std::string MemoryAccess::getAccessRelationStr() const {
342   return stringFromIslObj(AccessRelation);
343 }
344 
345 __isl_give isl_space *MemoryAccess::getAccessRelationSpace() const {
346   return isl_map_get_space(AccessRelation);
347 }
348 
349 isl_map *MemoryAccess::getNewAccessRelation() const {
350   return isl_map_copy(newAccessRelation);
351 }
352 
353 isl_basic_map *MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
354   isl_space *Space = isl_space_set_alloc(Statement->getIslCtx(), 0, 1);
355   Space = isl_space_align_params(Space, Statement->getDomainSpace());
356 
357   return isl_basic_map_from_domain_and_range(
358       isl_basic_set_universe(Statement->getDomainSpace()),
359       isl_basic_set_universe(Space));
360 }
361 
362 // Formalize no out-of-bound access assumption
363 //
364 // When delinearizing array accesses we optimistically assume that the
365 // delinearized accesses do not access out of bound locations (the subscript
366 // expression of each array evaluates for each statement instance that is
367 // executed to a value that is larger than zero and strictly smaller than the
368 // size of the corresponding dimension). The only exception is the outermost
369 // dimension for which we do not need to assume any upper bound.  At this point
370 // we formalize this assumption to ensure that at code generation time the
371 // relevant run-time checks can be generated.
372 //
373 // To find the set of constraints necessary to avoid out of bound accesses, we
374 // first build the set of data locations that are not within array bounds. We
375 // then apply the reverse access relation to obtain the set of iterations that
376 // may contain invalid accesses and reduce this set of iterations to the ones
377 // that are actually executed by intersecting them with the domain of the
378 // statement. If we now project out all loop dimensions, we obtain a set of
379 // parameters that may cause statement instances to be executed that may
380 // possibly yield out of bound memory accesses. The complement of these
381 // constraints is the set of constraints that needs to be assumed to ensure such
382 // statement instances are never executed.
383 void MemoryAccess::assumeNoOutOfBound(const IRAccess &Access) {
384   isl_space *Space = isl_space_range(getAccessRelationSpace());
385   isl_set *Outside = isl_set_empty(isl_space_copy(Space));
386   for (int i = 1, Size = Access.Subscripts.size(); i < Size; ++i) {
387     isl_local_space *LS = isl_local_space_from_space(isl_space_copy(Space));
388     isl_pw_aff *Var =
389         isl_pw_aff_var_on_domain(isl_local_space_copy(LS), isl_dim_set, i);
390     isl_pw_aff *Zero = isl_pw_aff_zero_on_domain(LS);
391 
392     isl_set *DimOutside;
393 
394     DimOutside = isl_pw_aff_lt_set(isl_pw_aff_copy(Var), Zero);
395     isl_pw_aff *SizeE = SCEVAffinator::getPwAff(Statement, Access.Sizes[i - 1]);
396 
397     SizeE = isl_pw_aff_drop_dims(SizeE, isl_dim_in, 0,
398                                  Statement->getNumIterators());
399     SizeE = isl_pw_aff_add_dims(SizeE, isl_dim_in,
400                                 isl_space_dim(Space, isl_dim_set));
401     SizeE = isl_pw_aff_set_tuple_id(SizeE, isl_dim_in,
402                                     isl_space_get_tuple_id(Space, isl_dim_set));
403 
404     DimOutside = isl_set_union(DimOutside, isl_pw_aff_le_set(SizeE, Var));
405 
406     Outside = isl_set_union(Outside, DimOutside);
407   }
408 
409   Outside = isl_set_apply(Outside, isl_map_reverse(getAccessRelation()));
410   Outside = isl_set_intersect(Outside, Statement->getDomain());
411   Outside = isl_set_params(Outside);
412   Outside = isl_set_complement(Outside);
413   Statement->getParent()->addAssumption(Outside);
414   isl_space_free(Space);
415 }
416 
417 MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst,
418                            ScopStmt *Statement)
419     : Statement(Statement), Inst(AccInst), newAccessRelation(nullptr) {
420 
421   isl_ctx *Ctx = Statement->getIslCtx();
422   BaseAddr = Access.getBase();
423   BaseName = getIslCompatibleName("MemRef_", getBaseAddr(), "");
424   isl_id *BaseAddrId = isl_id_alloc(Ctx, getBaseName().c_str(), nullptr);
425 
426   if (!Access.isAffine()) {
427     // We overapproximate non-affine accesses with a possible access to the
428     // whole array. For read accesses it does not make a difference, if an
429     // access must or may happen. However, for write accesses it is important to
430     // differentiate between writes that must happen and writes that may happen.
431     AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
432     AccessRelation =
433         isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
434     Type = Access.isRead() ? READ : MAY_WRITE;
435     return;
436   }
437 
438   Type = Access.isRead() ? READ : MUST_WRITE;
439 
440   isl_space *Space = isl_space_alloc(Ctx, 0, Statement->getNumIterators(), 0);
441   AccessRelation = isl_map_universe(Space);
442 
443   for (int i = 0, Size = Access.Subscripts.size(); i < Size; ++i) {
444     isl_pw_aff *Affine =
445         SCEVAffinator::getPwAff(Statement, Access.Subscripts[i]);
446 
447     if (Size == 1) {
448       // For the non delinearized arrays, divide the access function of the last
449       // subscript by the size of the elements in the array.
450       //
451       // A stride one array access in C expressed as A[i] is expressed in
452       // LLVM-IR as something like A[i * elementsize]. This hides the fact that
453       // two subsequent values of 'i' index two values that are stored next to
454       // each other in memory. By this division we make this characteristic
455       // obvious again.
456       isl_val *v = isl_val_int_from_si(Ctx, Access.getElemSizeInBytes());
457       Affine = isl_pw_aff_scale_down_val(Affine, v);
458     }
459 
460     isl_map *SubscriptMap = isl_map_from_pw_aff(Affine);
461 
462     AccessRelation = isl_map_flat_range_product(AccessRelation, SubscriptMap);
463   }
464 
465   Space = Statement->getDomainSpace();
466   AccessRelation = isl_map_set_tuple_id(
467       AccessRelation, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
468   AccessRelation =
469       isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
470 
471   assumeNoOutOfBound(Access);
472   isl_space_free(Space);
473 }
474 
475 void MemoryAccess::realignParams() {
476   isl_space *ParamSpace = Statement->getParent()->getParamSpace();
477   AccessRelation = isl_map_align_params(AccessRelation, ParamSpace);
478 }
479 
480 const std::string MemoryAccess::getReductionOperatorStr() const {
481   return MemoryAccess::getReductionOperatorStr(getReductionType());
482 }
483 
484 raw_ostream &polly::operator<<(raw_ostream &OS,
485                                MemoryAccess::ReductionType RT) {
486   if (RT == MemoryAccess::RT_NONE)
487     OS << "NONE";
488   else
489     OS << MemoryAccess::getReductionOperatorStr(RT);
490   return OS;
491 }
492 
493 void MemoryAccess::print(raw_ostream &OS) const {
494   switch (Type) {
495   case READ:
496     OS.indent(12) << "ReadAccess :=\t";
497     break;
498   case MUST_WRITE:
499     OS.indent(12) << "MustWriteAccess :=\t";
500     break;
501   case MAY_WRITE:
502     OS.indent(12) << "MayWriteAccess :=\t";
503     break;
504   }
505   OS << "[Reduction Type: " << getReductionType() << "]\n";
506   OS.indent(16) << getAccessRelationStr() << ";\n";
507 }
508 
509 void MemoryAccess::dump() const { print(errs()); }
510 
511 // Create a map in the size of the provided set domain, that maps from the
512 // one element of the provided set domain to another element of the provided
513 // set domain.
514 // The mapping is limited to all points that are equal in all but the last
515 // dimension and for which the last dimension of the input is strict smaller
516 // than the last dimension of the output.
517 //
518 //   getEqualAndLarger(set[i0, i1, ..., iX]):
519 //
520 //   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
521 //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
522 //
523 static isl_map *getEqualAndLarger(isl_space *setDomain) {
524   isl_space *Space = isl_space_map_from_set(setDomain);
525   isl_map *Map = isl_map_universe(isl_space_copy(Space));
526   isl_local_space *MapLocalSpace = isl_local_space_from_space(Space);
527   unsigned lastDimension = isl_map_dim(Map, isl_dim_in) - 1;
528 
529   // Set all but the last dimension to be equal for the input and output
530   //
531   //   input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
532   //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
533   for (unsigned i = 0; i < lastDimension; ++i)
534     Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
535 
536   // Set the last dimension of the input to be strict smaller than the
537   // last dimension of the output.
538   //
539   //   input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
540   //
541   isl_val *v;
542   isl_ctx *Ctx = isl_map_get_ctx(Map);
543   isl_constraint *c = isl_inequality_alloc(isl_local_space_copy(MapLocalSpace));
544   v = isl_val_int_from_si(Ctx, -1);
545   c = isl_constraint_set_coefficient_val(c, isl_dim_in, lastDimension, v);
546   v = isl_val_int_from_si(Ctx, 1);
547   c = isl_constraint_set_coefficient_val(c, isl_dim_out, lastDimension, v);
548   v = isl_val_int_from_si(Ctx, -1);
549   c = isl_constraint_set_constant_val(c, v);
550 
551   Map = isl_map_add_constraint(Map, c);
552 
553   isl_local_space_free(MapLocalSpace);
554   return Map;
555 }
556 
557 isl_set *MemoryAccess::getStride(__isl_take const isl_map *Schedule) const {
558   isl_map *S = const_cast<isl_map *>(Schedule);
559   isl_map *AccessRelation = getAccessRelation();
560   isl_space *Space = isl_space_range(isl_map_get_space(S));
561   isl_map *NextScatt = getEqualAndLarger(Space);
562 
563   S = isl_map_reverse(S);
564   NextScatt = isl_map_lexmin(NextScatt);
565 
566   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(S));
567   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(AccessRelation));
568   NextScatt = isl_map_apply_domain(NextScatt, S);
569   NextScatt = isl_map_apply_domain(NextScatt, AccessRelation);
570 
571   isl_set *Deltas = isl_map_deltas(NextScatt);
572   return Deltas;
573 }
574 
575 bool MemoryAccess::isStrideX(__isl_take const isl_map *Schedule,
576                              int StrideWidth) const {
577   isl_set *Stride, *StrideX;
578   bool IsStrideX;
579 
580   Stride = getStride(Schedule);
581   StrideX = isl_set_universe(isl_set_get_space(Stride));
582   StrideX = isl_set_fix_si(StrideX, isl_dim_set, 0, StrideWidth);
583   IsStrideX = isl_set_is_equal(Stride, StrideX);
584 
585   isl_set_free(StrideX);
586   isl_set_free(Stride);
587 
588   return IsStrideX;
589 }
590 
591 bool MemoryAccess::isStrideZero(const isl_map *Schedule) const {
592   return isStrideX(Schedule, 0);
593 }
594 
595 bool MemoryAccess::isScalar() const {
596   return isl_map_n_out(AccessRelation) == 0;
597 }
598 
599 bool MemoryAccess::isStrideOne(const isl_map *Schedule) const {
600   return isStrideX(Schedule, 1);
601 }
602 
603 void MemoryAccess::setNewAccessRelation(isl_map *newAccess) {
604   isl_map_free(newAccessRelation);
605   newAccessRelation = newAccess;
606 }
607 
608 //===----------------------------------------------------------------------===//
609 
610 isl_map *ScopStmt::getScattering() const { return isl_map_copy(Scattering); }
611 
612 void ScopStmt::restrictDomain(__isl_take isl_set *NewDomain) {
613   assert(isl_set_is_subset(NewDomain, Domain) &&
614          "New domain is not a subset of old domain!");
615   isl_set_free(Domain);
616   Domain = NewDomain;
617   Scattering = isl_map_intersect_domain(Scattering, isl_set_copy(Domain));
618 }
619 
620 void ScopStmt::setScattering(isl_map *NewScattering) {
621   assert(NewScattering && "New scattering is nullptr");
622   isl_map_free(Scattering);
623   Scattering = NewScattering;
624 }
625 
626 void ScopStmt::buildScattering(SmallVectorImpl<unsigned> &Scatter) {
627   unsigned NbIterators = getNumIterators();
628   unsigned NbScatteringDims = Parent.getMaxLoopDepth() * 2 + 1;
629 
630   isl_space *Space = isl_space_set_alloc(getIslCtx(), 0, NbScatteringDims);
631   Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering");
632 
633   Scattering = isl_map_from_domain_and_range(isl_set_universe(getDomainSpace()),
634                                              isl_set_universe(Space));
635 
636   // Loop dimensions.
637   for (unsigned i = 0; i < NbIterators; ++i)
638     Scattering =
639         isl_map_equate(Scattering, isl_dim_out, 2 * i + 1, isl_dim_in, i);
640 
641   // Constant dimensions
642   for (unsigned i = 0; i < NbIterators + 1; ++i)
643     Scattering = isl_map_fix_si(Scattering, isl_dim_out, 2 * i, Scatter[i]);
644 
645   // Fill scattering dimensions.
646   for (unsigned i = 2 * NbIterators + 1; i < NbScatteringDims; ++i)
647     Scattering = isl_map_fix_si(Scattering, isl_dim_out, i, 0);
648 
649   Scattering = isl_map_align_params(Scattering, Parent.getParamSpace());
650 }
651 
652 void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) {
653   for (auto &&Access : *tempScop.getAccessFunctions(BB)) {
654     MemAccs.push_back(new MemoryAccess(Access.first, Access.second, this));
655 
656     // We do not track locations for scalar memory accesses at the moment.
657     //
658     // We do not have a use for this information at the moment. If we need this
659     // at some point, the "instruction -> access" mapping needs to be enhanced
660     // as a single instruction could then possibly perform multiple accesses.
661     if (!Access.first.isScalar()) {
662       assert(!InstructionToAccess.count(Access.second) &&
663              "Unexpected 1-to-N mapping on instruction to access map!");
664       InstructionToAccess[Access.second] = MemAccs.back();
665     }
666   }
667 }
668 
669 void ScopStmt::realignParams() {
670   for (MemoryAccess *MA : *this)
671     MA->realignParams();
672 
673   Domain = isl_set_align_params(Domain, Parent.getParamSpace());
674   Scattering = isl_map_align_params(Scattering, Parent.getParamSpace());
675 }
676 
677 __isl_give isl_set *ScopStmt::buildConditionSet(const Comparison &Comp) {
678   isl_pw_aff *L = SCEVAffinator::getPwAff(this, Comp.getLHS());
679   isl_pw_aff *R = SCEVAffinator::getPwAff(this, Comp.getRHS());
680 
681   switch (Comp.getPred()) {
682   case ICmpInst::ICMP_EQ:
683     return isl_pw_aff_eq_set(L, R);
684   case ICmpInst::ICMP_NE:
685     return isl_pw_aff_ne_set(L, R);
686   case ICmpInst::ICMP_SLT:
687     return isl_pw_aff_lt_set(L, R);
688   case ICmpInst::ICMP_SLE:
689     return isl_pw_aff_le_set(L, R);
690   case ICmpInst::ICMP_SGT:
691     return isl_pw_aff_gt_set(L, R);
692   case ICmpInst::ICMP_SGE:
693     return isl_pw_aff_ge_set(L, R);
694   case ICmpInst::ICMP_ULT:
695   case ICmpInst::ICMP_UGT:
696   case ICmpInst::ICMP_ULE:
697   case ICmpInst::ICMP_UGE:
698     llvm_unreachable("Unsigned comparisons not yet supported");
699   default:
700     llvm_unreachable("Non integer predicate not supported");
701   }
702 }
703 
704 __isl_give isl_set *ScopStmt::addLoopBoundsToDomain(__isl_take isl_set *Domain,
705                                                     TempScop &tempScop) {
706   isl_space *Space;
707   isl_local_space *LocalSpace;
708 
709   Space = isl_set_get_space(Domain);
710   LocalSpace = isl_local_space_from_space(Space);
711 
712   for (int i = 0, e = getNumIterators(); i != e; ++i) {
713     isl_aff *Zero = isl_aff_zero_on_domain(isl_local_space_copy(LocalSpace));
714     isl_pw_aff *IV =
715         isl_pw_aff_from_aff(isl_aff_set_coefficient_si(Zero, isl_dim_in, i, 1));
716 
717     // 0 <= IV.
718     isl_set *LowerBound = isl_pw_aff_nonneg_set(isl_pw_aff_copy(IV));
719     Domain = isl_set_intersect(Domain, LowerBound);
720 
721     // IV <= LatchExecutions.
722     const Loop *L = getLoopForDimension(i);
723     const SCEV *LatchExecutions = tempScop.getLoopBound(L);
724     isl_pw_aff *UpperBound = SCEVAffinator::getPwAff(this, LatchExecutions);
725     isl_set *UpperBoundSet = isl_pw_aff_le_set(IV, UpperBound);
726     Domain = isl_set_intersect(Domain, UpperBoundSet);
727   }
728 
729   isl_local_space_free(LocalSpace);
730   return Domain;
731 }
732 
733 __isl_give isl_set *ScopStmt::addConditionsToDomain(__isl_take isl_set *Domain,
734                                                     TempScop &tempScop,
735                                                     const Region &CurRegion) {
736   const Region *TopRegion = tempScop.getMaxRegion().getParent(),
737                *CurrentRegion = &CurRegion;
738   const BasicBlock *BranchingBB = BB;
739 
740   do {
741     if (BranchingBB != CurrentRegion->getEntry()) {
742       if (const BBCond *Condition = tempScop.getBBCond(BranchingBB))
743         for (const auto &C : *Condition) {
744           isl_set *ConditionSet = buildConditionSet(C);
745           Domain = isl_set_intersect(Domain, ConditionSet);
746         }
747     }
748     BranchingBB = CurrentRegion->getEntry();
749     CurrentRegion = CurrentRegion->getParent();
750   } while (TopRegion != CurrentRegion);
751 
752   return Domain;
753 }
754 
755 __isl_give isl_set *ScopStmt::buildDomain(TempScop &tempScop,
756                                           const Region &CurRegion) {
757   isl_space *Space;
758   isl_set *Domain;
759   isl_id *Id;
760 
761   Space = isl_space_set_alloc(getIslCtx(), 0, getNumIterators());
762 
763   Id = isl_id_alloc(getIslCtx(), getBaseName(), this);
764 
765   Domain = isl_set_universe(Space);
766   Domain = addLoopBoundsToDomain(Domain, tempScop);
767   Domain = addConditionsToDomain(Domain, tempScop, CurRegion);
768   Domain = isl_set_set_tuple_id(Domain, Id);
769 
770   return Domain;
771 }
772 
773 ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
774                    BasicBlock &bb, SmallVectorImpl<Loop *> &Nest,
775                    SmallVectorImpl<unsigned> &Scatter)
776     : Parent(parent), BB(&bb), IVS(Nest.size()), NestLoops(Nest.size()) {
777   // Setup the induction variables.
778   for (unsigned i = 0, e = Nest.size(); i < e; ++i) {
779     if (!SCEVCodegen) {
780       PHINode *PN = Nest[i]->getCanonicalInductionVariable();
781       assert(PN && "Non canonical IV in Scop!");
782       IVS[i] = PN;
783     }
784     NestLoops[i] = Nest[i];
785   }
786 
787   BaseName = getIslCompatibleName("Stmt_", &bb, "");
788 
789   Domain = buildDomain(tempScop, CurRegion);
790   buildScattering(Scatter);
791   buildAccesses(tempScop, CurRegion);
792   checkForReductions();
793 }
794 
795 /// @brief Collect loads which might form a reduction chain with @p StoreMA
796 ///
797 /// Check if the stored value for @p StoreMA is a binary operator with one or
798 /// two loads as operands. If the binary operand is commutative & associative,
799 /// used only once (by @p StoreMA) and its load operands are also used only
800 /// once, we have found a possible reduction chain. It starts at an operand
801 /// load and includes the binary operator and @p StoreMA.
802 ///
803 /// Note: We allow only one use to ensure the load and binary operator cannot
804 ///       escape this block or into any other store except @p StoreMA.
805 void ScopStmt::collectCandiateReductionLoads(
806     MemoryAccess *StoreMA, SmallVectorImpl<MemoryAccess *> &Loads) {
807   auto *Store = dyn_cast<StoreInst>(StoreMA->getAccessInstruction());
808   if (!Store)
809     return;
810 
811   // Skip if there is not one binary operator between the load and the store
812   auto *BinOp = dyn_cast<BinaryOperator>(Store->getValueOperand());
813   if (!BinOp)
814     return;
815 
816   // Skip if the binary operators has multiple uses
817   if (BinOp->getNumUses() != 1)
818     return;
819 
820   // Skip if the opcode of the binary operator is not commutative/associative
821   if (!BinOp->isCommutative() || !BinOp->isAssociative())
822     return;
823 
824   // Skip if the binary operator is outside the current SCoP
825   if (BinOp->getParent() != Store->getParent())
826     return;
827 
828   // Skip if it is a multiplicative reduction and we disabled them
829   if (DisableMultiplicativeReductions &&
830       (BinOp->getOpcode() == Instruction::Mul ||
831        BinOp->getOpcode() == Instruction::FMul))
832     return;
833 
834   // Check the binary operator operands for a candidate load
835   auto *PossibleLoad0 = dyn_cast<LoadInst>(BinOp->getOperand(0));
836   auto *PossibleLoad1 = dyn_cast<LoadInst>(BinOp->getOperand(1));
837   if (!PossibleLoad0 && !PossibleLoad1)
838     return;
839 
840   // A load is only a candidate if it cannot escape (thus has only this use)
841   if (PossibleLoad0 && PossibleLoad0->getNumUses() == 1)
842     if (PossibleLoad0->getParent() == Store->getParent())
843       Loads.push_back(lookupAccessFor(PossibleLoad0));
844   if (PossibleLoad1 && PossibleLoad1->getNumUses() == 1)
845     if (PossibleLoad1->getParent() == Store->getParent())
846       Loads.push_back(lookupAccessFor(PossibleLoad1));
847 }
848 
849 /// @brief Check for reductions in this ScopStmt
850 ///
851 /// Iterate over all store memory accesses and check for valid binary reduction
852 /// like chains. For all candidates we check if they have the same base address
853 /// and there are no other accesses which overlap with them. The base address
854 /// check rules out impossible reductions candidates early. The overlap check,
855 /// together with the "only one user" check in collectCandiateReductionLoads,
856 /// guarantees that none of the intermediate results will escape during
857 /// execution of the loop nest. We basically check here that no other memory
858 /// access can access the same memory as the potential reduction.
859 void ScopStmt::checkForReductions() {
860   SmallVector<MemoryAccess *, 2> Loads;
861   SmallVector<std::pair<MemoryAccess *, MemoryAccess *>, 4> Candidates;
862 
863   // First collect candidate load-store reduction chains by iterating over all
864   // stores and collecting possible reduction loads.
865   for (MemoryAccess *StoreMA : MemAccs) {
866     if (StoreMA->isRead())
867       continue;
868 
869     Loads.clear();
870     collectCandiateReductionLoads(StoreMA, Loads);
871     for (MemoryAccess *LoadMA : Loads)
872       Candidates.push_back(std::make_pair(LoadMA, StoreMA));
873   }
874 
875   // Then check each possible candidate pair.
876   for (const auto &CandidatePair : Candidates) {
877     bool Valid = true;
878     isl_map *LoadAccs = CandidatePair.first->getAccessRelation();
879     isl_map *StoreAccs = CandidatePair.second->getAccessRelation();
880 
881     // Skip those with obviously unequal base addresses.
882     if (!isl_map_has_equal_space(LoadAccs, StoreAccs)) {
883       isl_map_free(LoadAccs);
884       isl_map_free(StoreAccs);
885       continue;
886     }
887 
888     // And check if the remaining for overlap with other memory accesses.
889     isl_map *AllAccsRel = isl_map_union(LoadAccs, StoreAccs);
890     AllAccsRel = isl_map_intersect_domain(AllAccsRel, getDomain());
891     isl_set *AllAccs = isl_map_range(AllAccsRel);
892 
893     for (MemoryAccess *MA : MemAccs) {
894       if (MA == CandidatePair.first || MA == CandidatePair.second)
895         continue;
896 
897       isl_map *AccRel =
898           isl_map_intersect_domain(MA->getAccessRelation(), getDomain());
899       isl_set *Accs = isl_map_range(AccRel);
900 
901       if (isl_set_has_equal_space(AllAccs, Accs) || isl_set_free(Accs)) {
902         isl_set *OverlapAccs = isl_set_intersect(Accs, isl_set_copy(AllAccs));
903         Valid = Valid && isl_set_is_empty(OverlapAccs);
904         isl_set_free(OverlapAccs);
905       }
906     }
907 
908     isl_set_free(AllAccs);
909     if (!Valid)
910       continue;
911 
912     const LoadInst *Load =
913         dyn_cast<const LoadInst>(CandidatePair.first->getAccessInstruction());
914     MemoryAccess::ReductionType RT =
915         getReductionType(dyn_cast<BinaryOperator>(Load->user_back()), Load);
916 
917     // If no overlapping access was found we mark the load and store as
918     // reduction like.
919     CandidatePair.first->markAsReductionLike(RT);
920     CandidatePair.second->markAsReductionLike(RT);
921   }
922 }
923 
924 std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
925 
926 std::string ScopStmt::getScatteringStr() const {
927   return stringFromIslObj(Scattering);
928 }
929 
930 unsigned ScopStmt::getNumParams() const { return Parent.getNumParams(); }
931 
932 unsigned ScopStmt::getNumIterators() const {
933   // The final read has one dimension with one element.
934   if (!BB)
935     return 1;
936 
937   return NestLoops.size();
938 }
939 
940 unsigned ScopStmt::getNumScattering() const {
941   return isl_map_dim(Scattering, isl_dim_out);
942 }
943 
944 const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
945 
946 const PHINode *
947 ScopStmt::getInductionVariableForDimension(unsigned Dimension) const {
948   return IVS[Dimension];
949 }
950 
951 const Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
952   return NestLoops[Dimension];
953 }
954 
955 isl_ctx *ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
956 
957 isl_set *ScopStmt::getDomain() const { return isl_set_copy(Domain); }
958 
959 isl_space *ScopStmt::getDomainSpace() const {
960   return isl_set_get_space(Domain);
961 }
962 
963 isl_id *ScopStmt::getDomainId() const { return isl_set_get_tuple_id(Domain); }
964 
965 ScopStmt::~ScopStmt() {
966   while (!MemAccs.empty()) {
967     delete MemAccs.back();
968     MemAccs.pop_back();
969   }
970 
971   isl_set_free(Domain);
972   isl_map_free(Scattering);
973 }
974 
975 void ScopStmt::print(raw_ostream &OS) const {
976   OS << "\t" << getBaseName() << "\n";
977   OS.indent(12) << "Domain :=\n";
978 
979   if (Domain) {
980     OS.indent(16) << getDomainStr() << ";\n";
981   } else
982     OS.indent(16) << "n/a\n";
983 
984   OS.indent(12) << "Scattering :=\n";
985 
986   if (Domain) {
987     OS.indent(16) << getScatteringStr() << ";\n";
988   } else
989     OS.indent(16) << "n/a\n";
990 
991   for (MemoryAccess *Access : MemAccs)
992     Access->print(OS);
993 }
994 
995 void ScopStmt::dump() const { print(dbgs()); }
996 
997 //===----------------------------------------------------------------------===//
998 /// Scop class implement
999 
1000 void Scop::setContext(__isl_take isl_set *NewContext) {
1001   NewContext = isl_set_align_params(NewContext, isl_set_get_space(Context));
1002   isl_set_free(Context);
1003   Context = NewContext;
1004 }
1005 
1006 void Scop::addParams(std::vector<const SCEV *> NewParameters) {
1007   for (const SCEV *Parameter : NewParameters) {
1008     if (ParameterIds.find(Parameter) != ParameterIds.end())
1009       continue;
1010 
1011     int dimension = Parameters.size();
1012 
1013     Parameters.push_back(Parameter);
1014     ParameterIds[Parameter] = dimension;
1015   }
1016 }
1017 
1018 __isl_give isl_id *Scop::getIdForParam(const SCEV *Parameter) const {
1019   ParamIdType::const_iterator IdIter = ParameterIds.find(Parameter);
1020 
1021   if (IdIter == ParameterIds.end())
1022     return nullptr;
1023 
1024   std::string ParameterName;
1025 
1026   if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
1027     Value *Val = ValueParameter->getValue();
1028     ParameterName = Val->getName();
1029   }
1030 
1031   if (ParameterName == "" || ParameterName.substr(0, 2) == "p_")
1032     ParameterName = "p_" + utostr_32(IdIter->second);
1033 
1034   return isl_id_alloc(getIslCtx(), ParameterName.c_str(),
1035                       const_cast<void *>((const void *)Parameter));
1036 }
1037 
1038 void Scop::buildContext() {
1039   isl_space *Space = isl_space_params_alloc(IslCtx, 0);
1040   Context = isl_set_universe(isl_space_copy(Space));
1041   AssumedContext = isl_set_universe(Space);
1042 }
1043 
1044 void Scop::addParameterBounds() {
1045   for (unsigned i = 0; i < isl_set_dim(Context, isl_dim_param); ++i) {
1046     isl_val *V;
1047     isl_id *Id;
1048     const SCEV *Scev;
1049     const IntegerType *T;
1050 
1051     Id = isl_set_get_dim_id(Context, isl_dim_param, i);
1052     Scev = (const SCEV *)isl_id_get_user(Id);
1053     T = dyn_cast<IntegerType>(Scev->getType());
1054     isl_id_free(Id);
1055 
1056     assert(T && "Not an integer type");
1057     int Width = T->getBitWidth();
1058 
1059     V = isl_val_int_from_si(IslCtx, Width - 1);
1060     V = isl_val_2exp(V);
1061     V = isl_val_neg(V);
1062     Context = isl_set_lower_bound_val(Context, isl_dim_param, i, V);
1063 
1064     V = isl_val_int_from_si(IslCtx, Width - 1);
1065     V = isl_val_2exp(V);
1066     V = isl_val_sub_ui(V, 1);
1067     Context = isl_set_upper_bound_val(Context, isl_dim_param, i, V);
1068   }
1069 }
1070 
1071 void Scop::realignParams() {
1072   // Add all parameters into a common model.
1073   isl_space *Space = isl_space_params_alloc(IslCtx, ParameterIds.size());
1074 
1075   for (const auto &ParamID : ParameterIds) {
1076     const SCEV *Parameter = ParamID.first;
1077     isl_id *id = getIdForParam(Parameter);
1078     Space = isl_space_set_dim_id(Space, isl_dim_param, ParamID.second, id);
1079   }
1080 
1081   // Align the parameters of all data structures to the model.
1082   Context = isl_set_align_params(Context, Space);
1083 
1084   for (ScopStmt *Stmt : *this)
1085     Stmt->realignParams();
1086 }
1087 
1088 void Scop::simplifyAssumedContext() {
1089   // The parameter constraints of the iteration domains give us a set of
1090   // constraints that need to hold for all cases where at least a single
1091   // statement iteration is executed in the whole scop. We now simplify the
1092   // assumed context under the assumption that such constraints hold and at
1093   // least a single statement iteration is executed. For cases where no
1094   // statement instances are executed, the assumptions we have taken about
1095   // the executed code do not matter and can be changed.
1096   //
1097   // WARNING: This only holds if the assumptions we have taken do not reduce
1098   //          the set of statement instances that are executed. Otherwise we
1099   //          may run into a case where the iteration domains suggest that
1100   //          for a certain set of parameter constraints no code is executed,
1101   //          but in the original program some computation would have been
1102   //          performed. In such a case, modifying the run-time conditions and
1103   //          possibly influencing the run-time check may cause certain scops
1104   //          to not be executed.
1105   //
1106   // Example:
1107   //
1108   //   When delinearizing the following code:
1109   //
1110   //     for (long i = 0; i < 100; i++)
1111   //       for (long j = 0; j < m; j++)
1112   //         A[i+p][j] = 1.0;
1113   //
1114   //   we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
1115   //   otherwise we would access out of bound data. Now, knowing that code is
1116   //   only executed for the case m >= 0, it is sufficient to assume p >= 0.
1117   AssumedContext =
1118       isl_set_gist_params(AssumedContext, isl_union_set_params(getDomains()));
1119 }
1120 
1121 Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution,
1122            isl_ctx *Context)
1123     : SE(&ScalarEvolution), R(tempScop.getMaxRegion()),
1124       MaxLoopDepth(tempScop.getMaxLoopDepth()) {
1125   IslCtx = Context;
1126   buildContext();
1127 
1128   SmallVector<Loop *, 8> NestLoops;
1129   SmallVector<unsigned, 8> Scatter;
1130 
1131   Scatter.assign(MaxLoopDepth + 1, 0);
1132 
1133   // Build the iteration domain, access functions and scattering functions
1134   // traversing the region tree.
1135   buildScop(tempScop, getRegion(), NestLoops, Scatter, LI);
1136 
1137   realignParams();
1138   addParameterBounds();
1139   simplifyAssumedContext();
1140 
1141   assert(NestLoops.empty() && "NestLoops not empty at top level!");
1142 }
1143 
1144 Scop::~Scop() {
1145   isl_set_free(Context);
1146   isl_set_free(AssumedContext);
1147 
1148   // Free the statements;
1149   for (ScopStmt *Stmt : *this)
1150     delete Stmt;
1151 }
1152 
1153 std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
1154 std::string Scop::getAssumedContextStr() const {
1155   return stringFromIslObj(AssumedContext);
1156 }
1157 
1158 std::string Scop::getNameStr() const {
1159   std::string ExitName, EntryName;
1160   raw_string_ostream ExitStr(ExitName);
1161   raw_string_ostream EntryStr(EntryName);
1162 
1163   R.getEntry()->printAsOperand(EntryStr, false);
1164   EntryStr.str();
1165 
1166   if (R.getExit()) {
1167     R.getExit()->printAsOperand(ExitStr, false);
1168     ExitStr.str();
1169   } else
1170     ExitName = "FunctionExit";
1171 
1172   return EntryName + "---" + ExitName;
1173 }
1174 
1175 __isl_give isl_set *Scop::getContext() const { return isl_set_copy(Context); }
1176 __isl_give isl_space *Scop::getParamSpace() const {
1177   return isl_set_get_space(this->Context);
1178 }
1179 
1180 __isl_give isl_set *Scop::getAssumedContext() const {
1181   return isl_set_copy(AssumedContext);
1182 }
1183 
1184 void Scop::addAssumption(__isl_take isl_set *Set) {
1185   AssumedContext = isl_set_intersect(AssumedContext, Set);
1186 }
1187 
1188 void Scop::printContext(raw_ostream &OS) const {
1189   OS << "Context:\n";
1190 
1191   if (!Context) {
1192     OS.indent(4) << "n/a\n\n";
1193     return;
1194   }
1195 
1196   OS.indent(4) << getContextStr() << "\n";
1197 
1198   OS.indent(4) << "Assumed Context:\n";
1199   if (!AssumedContext) {
1200     OS.indent(4) << "n/a\n\n";
1201     return;
1202   }
1203 
1204   OS.indent(4) << getAssumedContextStr() << "\n";
1205 
1206   for (const SCEV *Parameter : Parameters) {
1207     int Dim = ParameterIds.find(Parameter)->second;
1208     OS.indent(4) << "p" << Dim << ": " << *Parameter << "\n";
1209   }
1210 }
1211 
1212 void Scop::printStatements(raw_ostream &OS) const {
1213   OS << "Statements {\n";
1214 
1215   for (ScopStmt *Stmt : *this)
1216     OS.indent(4) << *Stmt;
1217 
1218   OS.indent(4) << "}\n";
1219 }
1220 
1221 void Scop::print(raw_ostream &OS) const {
1222   OS.indent(4) << "Function: " << getRegion().getEntry()->getParent()->getName()
1223                << "\n";
1224   OS.indent(4) << "Region: " << getNameStr() << "\n";
1225   printContext(OS.indent(4));
1226   printStatements(OS.indent(4));
1227 }
1228 
1229 void Scop::dump() const { print(dbgs()); }
1230 
1231 isl_ctx *Scop::getIslCtx() const { return IslCtx; }
1232 
1233 __isl_give isl_union_set *Scop::getDomains() {
1234   isl_union_set *Domain = isl_union_set_empty(getParamSpace());
1235 
1236   for (ScopStmt *Stmt : *this)
1237     Domain = isl_union_set_add_set(Domain, Stmt->getDomain());
1238 
1239   return Domain;
1240 }
1241 
1242 __isl_give isl_union_map *Scop::getMustWrites() {
1243   isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
1244 
1245   for (ScopStmt *Stmt : *this) {
1246     for (MemoryAccess *MA : *Stmt) {
1247       if (!MA->isMustWrite())
1248         continue;
1249 
1250       isl_set *Domain = Stmt->getDomain();
1251       isl_map *AccessDomain = MA->getAccessRelation();
1252       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1253       Write = isl_union_map_add_map(Write, AccessDomain);
1254     }
1255   }
1256   return isl_union_map_coalesce(Write);
1257 }
1258 
1259 __isl_give isl_union_map *Scop::getMayWrites() {
1260   isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
1261 
1262   for (ScopStmt *Stmt : *this) {
1263     for (MemoryAccess *MA : *Stmt) {
1264       if (!MA->isMayWrite())
1265         continue;
1266 
1267       isl_set *Domain = Stmt->getDomain();
1268       isl_map *AccessDomain = MA->getAccessRelation();
1269       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1270       Write = isl_union_map_add_map(Write, AccessDomain);
1271     }
1272   }
1273   return isl_union_map_coalesce(Write);
1274 }
1275 
1276 __isl_give isl_union_map *Scop::getWrites() {
1277   isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
1278 
1279   for (ScopStmt *Stmt : *this) {
1280     for (MemoryAccess *MA : *Stmt) {
1281       if (!MA->isWrite())
1282         continue;
1283 
1284       isl_set *Domain = Stmt->getDomain();
1285       isl_map *AccessDomain = MA->getAccessRelation();
1286       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1287       Write = isl_union_map_add_map(Write, AccessDomain);
1288     }
1289   }
1290   return isl_union_map_coalesce(Write);
1291 }
1292 
1293 __isl_give isl_union_map *Scop::getReads() {
1294   isl_union_map *Read = isl_union_map_empty(getParamSpace());
1295 
1296   for (ScopStmt *Stmt : *this) {
1297     for (MemoryAccess *MA : *Stmt) {
1298       if (!MA->isRead())
1299         continue;
1300 
1301       isl_set *Domain = Stmt->getDomain();
1302       isl_map *AccessDomain = MA->getAccessRelation();
1303 
1304       AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
1305       Read = isl_union_map_add_map(Read, AccessDomain);
1306     }
1307   }
1308   return isl_union_map_coalesce(Read);
1309 }
1310 
1311 __isl_give isl_union_map *Scop::getSchedule() {
1312   isl_union_map *Schedule = isl_union_map_empty(getParamSpace());
1313 
1314   for (ScopStmt *Stmt : *this)
1315     Schedule = isl_union_map_add_map(Schedule, Stmt->getScattering());
1316 
1317   return isl_union_map_coalesce(Schedule);
1318 }
1319 
1320 bool Scop::restrictDomains(__isl_take isl_union_set *Domain) {
1321   bool Changed = false;
1322   for (ScopStmt *Stmt : *this) {
1323     isl_union_set *StmtDomain = isl_union_set_from_set(Stmt->getDomain());
1324     isl_union_set *NewStmtDomain = isl_union_set_intersect(
1325         isl_union_set_copy(StmtDomain), isl_union_set_copy(Domain));
1326 
1327     if (isl_union_set_is_subset(StmtDomain, NewStmtDomain)) {
1328       isl_union_set_free(StmtDomain);
1329       isl_union_set_free(NewStmtDomain);
1330       continue;
1331     }
1332 
1333     Changed = true;
1334 
1335     isl_union_set_free(StmtDomain);
1336     NewStmtDomain = isl_union_set_coalesce(NewStmtDomain);
1337 
1338     if (isl_union_set_is_empty(NewStmtDomain)) {
1339       Stmt->restrictDomain(isl_set_empty(Stmt->getDomainSpace()));
1340       isl_union_set_free(NewStmtDomain);
1341     } else
1342       Stmt->restrictDomain(isl_set_from_union_set(NewStmtDomain));
1343   }
1344   isl_union_set_free(Domain);
1345   return Changed;
1346 }
1347 
1348 ScalarEvolution *Scop::getSE() const { return SE; }
1349 
1350 bool Scop::isTrivialBB(BasicBlock *BB, TempScop &tempScop) {
1351   if (tempScop.getAccessFunctions(BB))
1352     return false;
1353 
1354   return true;
1355 }
1356 
1357 void Scop::buildScop(TempScop &tempScop, const Region &CurRegion,
1358                      SmallVectorImpl<Loop *> &NestLoops,
1359                      SmallVectorImpl<unsigned> &Scatter, LoopInfo &LI) {
1360   Loop *L = castToLoop(CurRegion, LI);
1361 
1362   if (L)
1363     NestLoops.push_back(L);
1364 
1365   unsigned loopDepth = NestLoops.size();
1366   assert(Scatter.size() > loopDepth && "Scatter not big enough!");
1367 
1368   for (Region::const_element_iterator I = CurRegion.element_begin(),
1369                                       E = CurRegion.element_end();
1370        I != E; ++I)
1371     if (I->isSubRegion())
1372       buildScop(tempScop, *(I->getNodeAs<Region>()), NestLoops, Scatter, LI);
1373     else {
1374       BasicBlock *BB = I->getNodeAs<BasicBlock>();
1375 
1376       if (isTrivialBB(BB, tempScop))
1377         continue;
1378 
1379       Stmts.push_back(
1380           new ScopStmt(*this, tempScop, CurRegion, *BB, NestLoops, Scatter));
1381 
1382       // Increasing the Scattering function is OK for the moment, because
1383       // we are using a depth first iterator and the program is well structured.
1384       ++Scatter[loopDepth];
1385     }
1386 
1387   if (!L)
1388     return;
1389 
1390   // Exiting a loop region.
1391   Scatter[loopDepth] = 0;
1392   NestLoops.pop_back();
1393   ++Scatter[loopDepth - 1];
1394 }
1395 
1396 //===----------------------------------------------------------------------===//
1397 ScopInfo::ScopInfo() : RegionPass(ID), scop(0) {
1398   ctx = isl_ctx_alloc();
1399   isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
1400 }
1401 
1402 ScopInfo::~ScopInfo() {
1403   clear();
1404   isl_ctx_free(ctx);
1405 }
1406 
1407 void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
1408   AU.addRequired<LoopInfo>();
1409   AU.addRequired<RegionInfoPass>();
1410   AU.addRequired<ScalarEvolution>();
1411   AU.addRequired<TempScopInfo>();
1412   AU.setPreservesAll();
1413 }
1414 
1415 bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
1416   LoopInfo &LI = getAnalysis<LoopInfo>();
1417   ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
1418 
1419   TempScop *tempScop = getAnalysis<TempScopInfo>().getTempScop(R);
1420 
1421   // This region is no Scop.
1422   if (!tempScop) {
1423     scop = 0;
1424     return false;
1425   }
1426 
1427   // Statistics.
1428   ++ScopFound;
1429   if (tempScop->getMaxLoopDepth() > 0)
1430     ++RichScopFound;
1431 
1432   scop = new Scop(*tempScop, LI, SE, ctx);
1433 
1434   return false;
1435 }
1436 
1437 char ScopInfo::ID = 0;
1438 
1439 Pass *polly::createScopInfoPass() { return new ScopInfo(); }
1440 
1441 INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops",
1442                       "Polly - Create polyhedral description of Scops", false,
1443                       false);
1444 INITIALIZE_PASS_DEPENDENCY(LoopInfo);
1445 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
1446 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
1447 INITIALIZE_PASS_DEPENDENCY(TempScopInfo);
1448 INITIALIZE_PASS_END(ScopInfo, "polly-scops",
1449                     "Polly - Create polyhedral description of Scops", false,
1450                     false)
1451