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/Support/GICHelper.h"
24 #include "polly/Support/SCEVValidator.h"
25 #include "polly/Support/ScopHelper.h"
26 #include "polly/TempScopInfo.h"
27 #include "llvm/ADT/SetVector.h"
28 #include "llvm/ADT/Statistic.h"
29 #include "llvm/ADT/StringExtras.h"
30 #include "llvm/Analysis/LoopInfo.h"
31 #include "llvm/Analysis/RegionIterator.h"
32 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
33 #include "llvm/Support/CommandLine.h"
34 
35 #define DEBUG_TYPE "polly-scops"
36 #include "llvm/Support/Debug.h"
37 
38 #include "isl/constraint.h"
39 #include "isl/set.h"
40 #include "isl/map.h"
41 #include "isl/aff.h"
42 #include "isl/printer.h"
43 #include "isl/local_space.h"
44 #include "isl/options.h"
45 #include "isl/val.h"
46 #include <sstream>
47 #include <string>
48 #include <vector>
49 
50 using namespace llvm;
51 using namespace polly;
52 
53 STATISTIC(ScopFound, "Number of valid Scops");
54 STATISTIC(RichScopFound, "Number of Scops containing a loop");
55 
56 /// Translate a 'const SCEV *' expression in an isl_pw_aff.
57 struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
58 public:
59   /// @brief Translate a 'const SCEV *' to an isl_pw_aff.
60   ///
61   /// @param Stmt The location at which the scalar evolution expression
62   ///             is evaluated.
63   /// @param Expr The expression that is translated.
64   static __isl_give isl_pw_aff *getPwAff(ScopStmt *Stmt, const SCEV *Expr);
65 
66 private:
67   isl_ctx *Ctx;
68   int NbLoopSpaces;
69   const Scop *S;
70 
71   SCEVAffinator(const ScopStmt *Stmt);
72   int getLoopDepth(const Loop *L);
73 
74   __isl_give isl_pw_aff *visit(const SCEV *Expr);
75   __isl_give isl_pw_aff *visitConstant(const SCEVConstant *Expr);
76   __isl_give isl_pw_aff *visitTruncateExpr(const SCEVTruncateExpr *Expr);
77   __isl_give isl_pw_aff *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr);
78   __isl_give isl_pw_aff *visitSignExtendExpr(const SCEVSignExtendExpr *Expr);
79   __isl_give isl_pw_aff *visitAddExpr(const SCEVAddExpr *Expr);
80   __isl_give isl_pw_aff *visitMulExpr(const SCEVMulExpr *Expr);
81   __isl_give isl_pw_aff *visitUDivExpr(const SCEVUDivExpr *Expr);
82   __isl_give isl_pw_aff *visitAddRecExpr(const SCEVAddRecExpr *Expr);
83   __isl_give isl_pw_aff *visitSMaxExpr(const SCEVSMaxExpr *Expr);
84   __isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr);
85   __isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr);
86 
87   friend struct SCEVVisitor<SCEVAffinator, isl_pw_aff *>;
88 };
89 
90 SCEVAffinator::SCEVAffinator(const ScopStmt *Stmt)
91     : Ctx(Stmt->getIslCtx()), NbLoopSpaces(Stmt->getNumIterators()),
92       S(Stmt->getParent()) {}
93 
94 __isl_give isl_pw_aff *SCEVAffinator::getPwAff(ScopStmt *Stmt,
95                                                const SCEV *Scev) {
96   Scop *S = Stmt->getParent();
97   const Region *Reg = &S->getRegion();
98 
99   S->addParams(getParamsInAffineExpr(Reg, Scev, *S->getSE()));
100 
101   SCEVAffinator Affinator(Stmt);
102   return Affinator.visit(Scev);
103 }
104 
105 __isl_give isl_pw_aff *SCEVAffinator::visit(const SCEV *Expr) {
106   // In case the scev is a valid parameter, we do not further analyze this
107   // expression, but create a new parameter in the isl_pw_aff. This allows us
108   // to treat subexpressions that we cannot translate into an piecewise affine
109   // expression, as constant parameters of the piecewise affine expression.
110   if (isl_id *Id = S->getIdForParam(Expr)) {
111     isl_space *Space = isl_space_set_alloc(Ctx, 1, NbLoopSpaces);
112     Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
113 
114     isl_set *Domain = isl_set_universe(isl_space_copy(Space));
115     isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space));
116     Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
117 
118     return isl_pw_aff_alloc(Domain, Affine);
119   }
120 
121   return SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Expr);
122 }
123 
124 __isl_give isl_pw_aff *SCEVAffinator::visitConstant(const SCEVConstant *Expr) {
125   ConstantInt *Value = Expr->getValue();
126   isl_val *v;
127 
128   // LLVM does not define if an integer value is interpreted as a signed or
129   // unsigned value. Hence, without further information, it is unknown how
130   // this value needs to be converted to GMP. At the moment, we only support
131   // signed operations. So we just interpret it as signed. Later, there are
132   // two options:
133   //
134   // 1. We always interpret any value as signed and convert the values on
135   //    demand.
136   // 2. We pass down the signedness of the calculation and use it to interpret
137   //    this constant correctly.
138   v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
139 
140   isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
141   isl_local_space *ls = isl_local_space_from_space(isl_space_copy(Space));
142   isl_aff *Affine = isl_aff_zero_on_domain(ls);
143   isl_set *Domain = isl_set_universe(Space);
144 
145   Affine = isl_aff_add_constant_val(Affine, v);
146 
147   return isl_pw_aff_alloc(Domain, Affine);
148 }
149 
150 __isl_give isl_pw_aff *
151 SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
152   llvm_unreachable("SCEVTruncateExpr not yet supported");
153 }
154 
155 __isl_give isl_pw_aff *
156 SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
157   llvm_unreachable("SCEVZeroExtendExpr not yet supported");
158 }
159 
160 __isl_give isl_pw_aff *
161 SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
162   // Assuming the value is signed, a sign extension is basically a noop.
163   // TODO: Reconsider this as soon as we support unsigned values.
164   return visit(Expr->getOperand());
165 }
166 
167 __isl_give isl_pw_aff *SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
168   isl_pw_aff *Sum = visit(Expr->getOperand(0));
169 
170   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
171     isl_pw_aff *NextSummand = visit(Expr->getOperand(i));
172     Sum = isl_pw_aff_add(Sum, NextSummand);
173   }
174 
175   // TODO: Check for NSW and NUW.
176 
177   return Sum;
178 }
179 
180 __isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) {
181   isl_pw_aff *Product = visit(Expr->getOperand(0));
182 
183   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
184     isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
185 
186     if (!isl_pw_aff_is_cst(Product) && !isl_pw_aff_is_cst(NextOperand)) {
187       isl_pw_aff_free(Product);
188       isl_pw_aff_free(NextOperand);
189       return NULL;
190     }
191 
192     Product = isl_pw_aff_mul(Product, NextOperand);
193   }
194 
195   // TODO: Check for NSW and NUW.
196   return Product;
197 }
198 
199 __isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) {
200   llvm_unreachable("SCEVUDivExpr not yet supported");
201 }
202 
203 __isl_give isl_pw_aff *
204 SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
205   assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
206 
207   // Directly generate isl_pw_aff for Expr if 'start' is zero.
208   if (Expr->getStart()->isZero()) {
209     assert(S->getRegion().contains(Expr->getLoop()) &&
210            "Scop does not contain the loop referenced in this AddRec");
211 
212     isl_pw_aff *Start = visit(Expr->getStart());
213     isl_pw_aff *Step = visit(Expr->getOperand(1));
214     isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
215     isl_local_space *LocalSpace = isl_local_space_from_space(Space);
216 
217     int loopDimension = getLoopDepth(Expr->getLoop());
218 
219     isl_aff *LAff = isl_aff_set_coefficient_si(
220         isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
221     isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
222 
223     // TODO: Do we need to check for NSW and NUW?
224     return isl_pw_aff_add(Start, isl_pw_aff_mul(Step, LPwAff));
225   }
226 
227   // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
228   // if 'start' is not zero.
229   ScalarEvolution &SE = *S->getSE();
230   const SCEV *ZeroStartExpr = SE.getAddRecExpr(
231       SE.getConstant(Expr->getStart()->getType(), 0),
232       Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
233 
234   isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr);
235   isl_pw_aff *Start = visit(Expr->getStart());
236 
237   return isl_pw_aff_add(ZeroStartResult, Start);
238 }
239 
240 __isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) {
241   isl_pw_aff *Max = visit(Expr->getOperand(0));
242 
243   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
244     isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
245     Max = isl_pw_aff_max(Max, NextOperand);
246   }
247 
248   return Max;
249 }
250 
251 __isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) {
252   llvm_unreachable("SCEVUMaxExpr not yet supported");
253 }
254 
255 __isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) {
256   llvm_unreachable("Unknowns are always parameters");
257 }
258 
259 int SCEVAffinator::getLoopDepth(const Loop *L) {
260   Loop *outerLoop = S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L));
261   assert(outerLoop && "Scop does not contain this loop");
262   return L->getLoopDepth() - outerLoop->getLoopDepth();
263 }
264 
265 //===----------------------------------------------------------------------===//
266 
267 MemoryAccess::~MemoryAccess() {
268   isl_map_free(AccessRelation);
269   isl_map_free(newAccessRelation);
270 }
271 
272 static void replace(std::string &str, const std::string &find,
273                     const std::string &replace) {
274   size_t pos = 0;
275   while ((pos = str.find(find, pos)) != std::string::npos) {
276     str.replace(pos, find.length(), replace);
277     pos += replace.length();
278   }
279 }
280 
281 static void makeIslCompatible(std::string &str) {
282   str.erase(0, 1);
283   replace(str, ".", "_");
284   replace(str, "\"", "_");
285 }
286 
287 void MemoryAccess::setBaseName() {
288   raw_string_ostream OS(BaseName);
289   getBaseAddr()->printAsOperand(OS, false);
290   BaseName = OS.str();
291 
292   makeIslCompatible(BaseName);
293   BaseName = "MemRef_" + BaseName;
294 }
295 
296 isl_map *MemoryAccess::getAccessRelation() const {
297   return isl_map_copy(AccessRelation);
298 }
299 
300 std::string MemoryAccess::getAccessRelationStr() const {
301   return stringFromIslObj(AccessRelation);
302 }
303 
304 isl_map *MemoryAccess::getNewAccessRelation() const {
305   return isl_map_copy(newAccessRelation);
306 }
307 
308 isl_basic_map *MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
309   isl_space *Space = isl_space_set_alloc(Statement->getIslCtx(), 0, 1);
310   Space = isl_space_set_tuple_name(Space, isl_dim_set, getBaseName().c_str());
311   Space = isl_space_align_params(Space, Statement->getDomainSpace());
312 
313   return isl_basic_map_from_domain_and_range(
314       isl_basic_set_universe(Statement->getDomainSpace()),
315       isl_basic_set_universe(Space));
316 }
317 
318 MemoryAccess::MemoryAccess(const IRAccess &Access, const Instruction *AccInst,
319                            ScopStmt *Statement)
320     : Inst(AccInst) {
321   newAccessRelation = NULL;
322   statement = Statement;
323 
324   BaseAddr = Access.getBase();
325   setBaseName();
326 
327   if (!Access.isAffine()) {
328     // We overapproximate non-affine accesses with a possible access to the
329     // whole array. For read accesses it does not make a difference, if an
330     // access must or may happen. However, for write accesses it is important to
331     // differentiate between writes that must happen and writes that may happen.
332     AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
333     Type = Access.isRead() ? READ : MAY_WRITE;
334     return;
335   }
336 
337   Type = Access.isRead() ? READ : MUST_WRITE;
338 
339   isl_pw_aff *Affine = SCEVAffinator::getPwAff(Statement, Access.getOffset());
340 
341   // Divide the access function by the size of the elements in the array.
342   //
343   // A stride one array access in C expressed as A[i] is expressed in LLVM-IR
344   // as something like A[i * elementsize]. This hides the fact that two
345   // subsequent values of 'i' index two values that are stored next to each
346   // other in memory. By this division we make this characteristic obvious
347   // again.
348   isl_val *v;
349   v = isl_val_int_from_si(isl_pw_aff_get_ctx(Affine),
350                           Access.getElemSizeInBytes());
351   Affine = isl_pw_aff_scale_down_val(Affine, v);
352 
353   AccessRelation = isl_map_from_pw_aff(Affine);
354   isl_space *Space = Statement->getDomainSpace();
355   AccessRelation = isl_map_set_tuple_id(
356       AccessRelation, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
357   isl_space_free(Space);
358   AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_out,
359                                           getBaseName().c_str());
360 }
361 
362 void MemoryAccess::realignParams() {
363   isl_space *ParamSpace = statement->getParent()->getParamSpace();
364   AccessRelation = isl_map_align_params(AccessRelation, ParamSpace);
365 }
366 
367 MemoryAccess::MemoryAccess(const Value *BaseAddress, ScopStmt *Statement) {
368   newAccessRelation = NULL;
369   BaseAddr = BaseAddress;
370   Type = READ;
371   statement = Statement;
372 
373   isl_basic_map *BasicAccessMap = createBasicAccessMap(Statement);
374   AccessRelation = isl_map_from_basic_map(BasicAccessMap);
375   isl_space *ParamSpace = Statement->getParent()->getParamSpace();
376   AccessRelation = isl_map_align_params(AccessRelation, ParamSpace);
377 }
378 
379 void MemoryAccess::print(raw_ostream &OS) const {
380   switch (Type) {
381   case READ:
382     OS.indent(12) << "ReadAccess := \n";
383     break;
384   case MUST_WRITE:
385     OS.indent(12) << "MustWriteAccess := \n";
386     break;
387   case MAY_WRITE:
388     OS.indent(12) << "MayWriteAccess := \n";
389     break;
390   }
391   OS.indent(16) << getAccessRelationStr() << ";\n";
392 }
393 
394 void MemoryAccess::dump() const { print(errs()); }
395 
396 // Create a map in the size of the provided set domain, that maps from the
397 // one element of the provided set domain to another element of the provided
398 // set domain.
399 // The mapping is limited to all points that are equal in all but the last
400 // dimension and for which the last dimension of the input is strict smaller
401 // than the last dimension of the output.
402 //
403 //   getEqualAndLarger(set[i0, i1, ..., iX]):
404 //
405 //   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
406 //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
407 //
408 static isl_map *getEqualAndLarger(isl_space *setDomain) {
409   isl_space *Space = isl_space_map_from_set(setDomain);
410   isl_map *Map = isl_map_universe(isl_space_copy(Space));
411   isl_local_space *MapLocalSpace = isl_local_space_from_space(Space);
412   unsigned lastDimension = isl_map_dim(Map, isl_dim_in) - 1;
413 
414   // Set all but the last dimension to be equal for the input and output
415   //
416   //   input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
417   //     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
418   for (unsigned i = 0; i < lastDimension; ++i)
419     Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
420 
421   // Set the last dimension of the input to be strict smaller than the
422   // last dimension of the output.
423   //
424   //   input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
425   //
426   isl_val *v;
427   isl_ctx *Ctx = isl_map_get_ctx(Map);
428   isl_constraint *c = isl_inequality_alloc(isl_local_space_copy(MapLocalSpace));
429   v = isl_val_int_from_si(Ctx, -1);
430   c = isl_constraint_set_coefficient_val(c, isl_dim_in, lastDimension, v);
431   v = isl_val_int_from_si(Ctx, 1);
432   c = isl_constraint_set_coefficient_val(c, isl_dim_out, lastDimension, v);
433   v = isl_val_int_from_si(Ctx, -1);
434   c = isl_constraint_set_constant_val(c, v);
435 
436   Map = isl_map_add_constraint(Map, c);
437 
438   isl_local_space_free(MapLocalSpace);
439   return Map;
440 }
441 
442 isl_set *MemoryAccess::getStride(__isl_take const isl_map *Schedule) const {
443   isl_map *S = const_cast<isl_map *>(Schedule);
444   isl_map *AccessRelation = getAccessRelation();
445   isl_space *Space = isl_space_range(isl_map_get_space(S));
446   isl_map *NextScatt = getEqualAndLarger(Space);
447 
448   S = isl_map_reverse(S);
449   NextScatt = isl_map_lexmin(NextScatt);
450 
451   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(S));
452   NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(AccessRelation));
453   NextScatt = isl_map_apply_domain(NextScatt, S);
454   NextScatt = isl_map_apply_domain(NextScatt, AccessRelation);
455 
456   isl_set *Deltas = isl_map_deltas(NextScatt);
457   return Deltas;
458 }
459 
460 bool MemoryAccess::isStrideX(__isl_take const isl_map *Schedule,
461                              int StrideWidth) const {
462   isl_set *Stride, *StrideX;
463   bool IsStrideX;
464 
465   Stride = getStride(Schedule);
466   StrideX = isl_set_universe(isl_set_get_space(Stride));
467   StrideX = isl_set_fix_si(StrideX, isl_dim_set, 0, StrideWidth);
468   IsStrideX = isl_set_is_equal(Stride, StrideX);
469 
470   isl_set_free(StrideX);
471   isl_set_free(Stride);
472 
473   return IsStrideX;
474 }
475 
476 bool MemoryAccess::isStrideZero(const isl_map *Schedule) const {
477   return isStrideX(Schedule, 0);
478 }
479 
480 bool MemoryAccess::isStrideOne(const isl_map *Schedule) const {
481   return isStrideX(Schedule, 1);
482 }
483 
484 void MemoryAccess::setNewAccessRelation(isl_map *newAccess) {
485   isl_map_free(newAccessRelation);
486   newAccessRelation = newAccess;
487 }
488 
489 //===----------------------------------------------------------------------===//
490 
491 isl_map *ScopStmt::getScattering() const { return isl_map_copy(Scattering); }
492 
493 void ScopStmt::setScattering(isl_map *NewScattering) {
494   isl_map_free(Scattering);
495   Scattering = NewScattering;
496 }
497 
498 void ScopStmt::buildScattering(SmallVectorImpl<unsigned> &Scatter) {
499   unsigned NbIterators = getNumIterators();
500   unsigned NbScatteringDims = Parent.getMaxLoopDepth() * 2 + 1;
501 
502   isl_space *Space = isl_space_set_alloc(getIslCtx(), 0, NbScatteringDims);
503   Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering");
504 
505   Scattering = isl_map_from_domain_and_range(isl_set_universe(getDomainSpace()),
506                                              isl_set_universe(Space));
507 
508   // Loop dimensions.
509   for (unsigned i = 0; i < NbIterators; ++i)
510     Scattering =
511         isl_map_equate(Scattering, isl_dim_out, 2 * i + 1, isl_dim_in, i);
512 
513   // Constant dimensions
514   for (unsigned i = 0; i < NbIterators + 1; ++i)
515     Scattering = isl_map_fix_si(Scattering, isl_dim_out, 2 * i, Scatter[i]);
516 
517   // Fill scattering dimensions.
518   for (unsigned i = 2 * NbIterators + 1; i < NbScatteringDims; ++i)
519     Scattering = isl_map_fix_si(Scattering, isl_dim_out, i, 0);
520 
521   Scattering = isl_map_align_params(Scattering, Parent.getParamSpace());
522 }
523 
524 void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) {
525   const AccFuncSetType *AccFuncs = tempScop.getAccessFunctions(BB);
526 
527   for (AccFuncSetType::const_iterator I = AccFuncs->begin(),
528                                       E = AccFuncs->end();
529        I != E; ++I) {
530     MemAccs.push_back(new MemoryAccess(I->first, I->second, this));
531     assert(!InstructionToAccess.count(I->second) &&
532            "Unexpected 1-to-N mapping on instruction to access map!");
533     InstructionToAccess[I->second] = MemAccs.back();
534   }
535 }
536 
537 void ScopStmt::realignParams() {
538   for (memacc_iterator MI = memacc_begin(), ME = memacc_end(); MI != ME; ++MI)
539     (*MI)->realignParams();
540 
541   Domain = isl_set_align_params(Domain, Parent.getParamSpace());
542   Scattering = isl_map_align_params(Scattering, Parent.getParamSpace());
543 }
544 
545 __isl_give isl_set *ScopStmt::buildConditionSet(const Comparison &Comp) {
546   isl_pw_aff *L = SCEVAffinator::getPwAff(this, Comp.getLHS());
547   isl_pw_aff *R = SCEVAffinator::getPwAff(this, Comp.getRHS());
548 
549   switch (Comp.getPred()) {
550   case ICmpInst::ICMP_EQ:
551     return isl_pw_aff_eq_set(L, R);
552   case ICmpInst::ICMP_NE:
553     return isl_pw_aff_ne_set(L, R);
554   case ICmpInst::ICMP_SLT:
555     return isl_pw_aff_lt_set(L, R);
556   case ICmpInst::ICMP_SLE:
557     return isl_pw_aff_le_set(L, R);
558   case ICmpInst::ICMP_SGT:
559     return isl_pw_aff_gt_set(L, R);
560   case ICmpInst::ICMP_SGE:
561     return isl_pw_aff_ge_set(L, R);
562   case ICmpInst::ICMP_ULT:
563   case ICmpInst::ICMP_UGT:
564   case ICmpInst::ICMP_ULE:
565   case ICmpInst::ICMP_UGE:
566     llvm_unreachable("Unsigned comparisons not yet supported");
567   default:
568     llvm_unreachable("Non integer predicate not supported");
569   }
570 }
571 
572 __isl_give isl_set *ScopStmt::addLoopBoundsToDomain(__isl_take isl_set *Domain,
573                                                     TempScop &tempScop) {
574   isl_space *Space;
575   isl_local_space *LocalSpace;
576 
577   Space = isl_set_get_space(Domain);
578   LocalSpace = isl_local_space_from_space(Space);
579 
580   for (int i = 0, e = getNumIterators(); i != e; ++i) {
581     isl_aff *Zero = isl_aff_zero_on_domain(isl_local_space_copy(LocalSpace));
582     isl_pw_aff *IV =
583         isl_pw_aff_from_aff(isl_aff_set_coefficient_si(Zero, isl_dim_in, i, 1));
584 
585     // 0 <= IV.
586     isl_set *LowerBound = isl_pw_aff_nonneg_set(isl_pw_aff_copy(IV));
587     Domain = isl_set_intersect(Domain, LowerBound);
588 
589     // IV <= LatchExecutions.
590     const Loop *L = getLoopForDimension(i);
591     const SCEV *LatchExecutions = tempScop.getLoopBound(L);
592     isl_pw_aff *UpperBound = SCEVAffinator::getPwAff(this, LatchExecutions);
593     isl_set *UpperBoundSet = isl_pw_aff_le_set(IV, UpperBound);
594     Domain = isl_set_intersect(Domain, UpperBoundSet);
595   }
596 
597   isl_local_space_free(LocalSpace);
598   return Domain;
599 }
600 
601 __isl_give isl_set *ScopStmt::addConditionsToDomain(__isl_take isl_set *Domain,
602                                                     TempScop &tempScop,
603                                                     const Region &CurRegion) {
604   const Region *TopRegion = tempScop.getMaxRegion().getParent(),
605                *CurrentRegion = &CurRegion;
606   const BasicBlock *BranchingBB = BB;
607 
608   do {
609     if (BranchingBB != CurrentRegion->getEntry()) {
610       if (const BBCond *Condition = tempScop.getBBCond(BranchingBB))
611         for (BBCond::const_iterator CI = Condition->begin(),
612                                     CE = Condition->end();
613              CI != CE; ++CI) {
614           isl_set *ConditionSet = buildConditionSet(*CI);
615           Domain = isl_set_intersect(Domain, ConditionSet);
616         }
617     }
618     BranchingBB = CurrentRegion->getEntry();
619     CurrentRegion = CurrentRegion->getParent();
620   } while (TopRegion != CurrentRegion);
621 
622   return Domain;
623 }
624 
625 __isl_give isl_set *ScopStmt::buildDomain(TempScop &tempScop,
626                                           const Region &CurRegion) {
627   isl_space *Space;
628   isl_set *Domain;
629   isl_id *Id;
630 
631   Space = isl_space_set_alloc(getIslCtx(), 0, getNumIterators());
632 
633   Id = isl_id_alloc(getIslCtx(), getBaseName(), this);
634 
635   Domain = isl_set_universe(Space);
636   Domain = addLoopBoundsToDomain(Domain, tempScop);
637   Domain = addConditionsToDomain(Domain, tempScop, CurRegion);
638   Domain = isl_set_set_tuple_id(Domain, Id);
639 
640   return Domain;
641 }
642 
643 ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
644                    BasicBlock &bb, SmallVectorImpl<Loop *> &Nest,
645                    SmallVectorImpl<unsigned> &Scatter)
646     : Parent(parent), BB(&bb), IVS(Nest.size()), NestLoops(Nest.size()) {
647   // Setup the induction variables.
648   for (unsigned i = 0, e = Nest.size(); i < e; ++i) {
649     if (!SCEVCodegen) {
650       PHINode *PN = Nest[i]->getCanonicalInductionVariable();
651       assert(PN && "Non canonical IV in Scop!");
652       IVS[i] = PN;
653     }
654     NestLoops[i] = Nest[i];
655   }
656 
657   raw_string_ostream OS(BaseName);
658   bb.printAsOperand(OS, false);
659   BaseName = OS.str();
660 
661   makeIslCompatible(BaseName);
662   BaseName = "Stmt_" + BaseName;
663 
664   Domain = buildDomain(tempScop, CurRegion);
665   buildScattering(Scatter);
666   buildAccesses(tempScop, CurRegion);
667 }
668 
669 std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
670 
671 std::string ScopStmt::getScatteringStr() const {
672   return stringFromIslObj(Scattering);
673 }
674 
675 unsigned ScopStmt::getNumParams() const { return Parent.getNumParams(); }
676 
677 unsigned ScopStmt::getNumIterators() const {
678   // The final read has one dimension with one element.
679   if (!BB)
680     return 1;
681 
682   return NestLoops.size();
683 }
684 
685 unsigned ScopStmt::getNumScattering() const {
686   return isl_map_dim(Scattering, isl_dim_out);
687 }
688 
689 const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
690 
691 const PHINode *
692 ScopStmt::getInductionVariableForDimension(unsigned Dimension) const {
693   return IVS[Dimension];
694 }
695 
696 const Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
697   return NestLoops[Dimension];
698 }
699 
700 isl_ctx *ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
701 
702 isl_set *ScopStmt::getDomain() const { return isl_set_copy(Domain); }
703 
704 isl_space *ScopStmt::getDomainSpace() const {
705   return isl_set_get_space(Domain);
706 }
707 
708 isl_id *ScopStmt::getDomainId() const { return isl_set_get_tuple_id(Domain); }
709 
710 ScopStmt::~ScopStmt() {
711   while (!MemAccs.empty()) {
712     delete MemAccs.back();
713     MemAccs.pop_back();
714   }
715 
716   isl_set_free(Domain);
717   isl_map_free(Scattering);
718 }
719 
720 void ScopStmt::print(raw_ostream &OS) const {
721   OS << "\t" << getBaseName() << "\n";
722 
723   OS.indent(12) << "Domain :=\n";
724 
725   if (Domain) {
726     OS.indent(16) << getDomainStr() << ";\n";
727   } else
728     OS.indent(16) << "n/a\n";
729 
730   OS.indent(12) << "Scattering :=\n";
731 
732   if (Domain) {
733     OS.indent(16) << getScatteringStr() << ";\n";
734   } else
735     OS.indent(16) << "n/a\n";
736 
737   for (MemoryAccessVec::const_iterator I = MemAccs.begin(), E = MemAccs.end();
738        I != E; ++I)
739     (*I)->print(OS);
740 }
741 
742 void ScopStmt::dump() const { print(dbgs()); }
743 
744 //===----------------------------------------------------------------------===//
745 /// Scop class implement
746 
747 void Scop::setContext(__isl_take isl_set *NewContext) {
748   NewContext = isl_set_align_params(NewContext, isl_set_get_space(Context));
749   isl_set_free(Context);
750   Context = NewContext;
751 }
752 
753 void Scop::addParams(std::vector<const SCEV *> NewParameters) {
754   for (std::vector<const SCEV *>::iterator PI = NewParameters.begin(),
755                                            PE = NewParameters.end();
756        PI != PE; ++PI) {
757     const SCEV *Parameter = *PI;
758 
759     if (ParameterIds.find(Parameter) != ParameterIds.end())
760       continue;
761 
762     int dimension = Parameters.size();
763 
764     Parameters.push_back(Parameter);
765     ParameterIds[Parameter] = dimension;
766   }
767 }
768 
769 __isl_give isl_id *Scop::getIdForParam(const SCEV *Parameter) const {
770   ParamIdType::const_iterator IdIter = ParameterIds.find(Parameter);
771 
772   if (IdIter == ParameterIds.end())
773     return NULL;
774 
775   std::string ParameterName;
776 
777   if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
778     Value *Val = ValueParameter->getValue();
779     ParameterName = Val->getName();
780   }
781 
782   if (ParameterName == "" || ParameterName.substr(0, 2) == "p_")
783     ParameterName = "p_" + utostr_32(IdIter->second);
784 
785   return isl_id_alloc(getIslCtx(), ParameterName.c_str(), (void *)Parameter);
786 }
787 
788 void Scop::buildContext() {
789   isl_space *Space = isl_space_params_alloc(IslCtx, 0);
790   Context = isl_set_universe(isl_space_copy(Space));
791   AssumedContext = isl_set_universe(Space);
792 }
793 
794 void Scop::addParameterBounds() {
795   for (unsigned i = 0; i < isl_set_dim(Context, isl_dim_param); ++i) {
796     isl_val *V;
797     isl_id *Id;
798     const SCEV *Scev;
799     const IntegerType *T;
800 
801     Id = isl_set_get_dim_id(Context, isl_dim_param, i);
802     Scev = (const SCEV *)isl_id_get_user(Id);
803     T = dyn_cast<IntegerType>(Scev->getType());
804     isl_id_free(Id);
805 
806     assert(T && "Not an integer type");
807     int Width = T->getBitWidth();
808 
809     V = isl_val_int_from_si(IslCtx, Width - 1);
810     V = isl_val_2exp(V);
811     V = isl_val_neg(V);
812     Context = isl_set_lower_bound_val(Context, isl_dim_param, i, V);
813 
814     V = isl_val_int_from_si(IslCtx, Width - 1);
815     V = isl_val_2exp(V);
816     V = isl_val_sub_ui(V, 1);
817     Context = isl_set_upper_bound_val(Context, isl_dim_param, i, V);
818   }
819 }
820 
821 void Scop::realignParams() {
822   // Add all parameters into a common model.
823   isl_space *Space = isl_space_params_alloc(IslCtx, ParameterIds.size());
824 
825   for (ParamIdType::iterator PI = ParameterIds.begin(), PE = ParameterIds.end();
826        PI != PE; ++PI) {
827     const SCEV *Parameter = PI->first;
828     isl_id *id = getIdForParam(Parameter);
829     Space = isl_space_set_dim_id(Space, isl_dim_param, PI->second, id);
830   }
831 
832   // Align the parameters of all data structures to the model.
833   Context = isl_set_align_params(Context, Space);
834 
835   for (iterator I = begin(), E = end(); I != E; ++I)
836     (*I)->realignParams();
837 }
838 
839 Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution,
840            isl_ctx *Context)
841     : SE(&ScalarEvolution), R(tempScop.getMaxRegion()),
842       MaxLoopDepth(tempScop.getMaxLoopDepth()) {
843   IslCtx = Context;
844   buildContext();
845 
846   SmallVector<Loop *, 8> NestLoops;
847   SmallVector<unsigned, 8> Scatter;
848 
849   Scatter.assign(MaxLoopDepth + 1, 0);
850 
851   // Build the iteration domain, access functions and scattering functions
852   // traversing the region tree.
853   buildScop(tempScop, getRegion(), NestLoops, Scatter, LI);
854 
855   realignParams();
856   addParameterBounds();
857 
858   assert(NestLoops.empty() && "NestLoops not empty at top level!");
859 }
860 
861 Scop::~Scop() {
862   isl_set_free(Context);
863   isl_set_free(AssumedContext);
864 
865   // Free the statements;
866   for (iterator I = begin(), E = end(); I != E; ++I)
867     delete *I;
868 }
869 
870 std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
871 
872 std::string Scop::getNameStr() const {
873   std::string ExitName, EntryName;
874   raw_string_ostream ExitStr(ExitName);
875   raw_string_ostream EntryStr(EntryName);
876 
877   R.getEntry()->printAsOperand(EntryStr, false);
878   EntryStr.str();
879 
880   if (R.getExit()) {
881     R.getExit()->printAsOperand(ExitStr, false);
882     ExitStr.str();
883   } else
884     ExitName = "FunctionExit";
885 
886   return EntryName + "---" + ExitName;
887 }
888 
889 __isl_give isl_set *Scop::getContext() const { return isl_set_copy(Context); }
890 __isl_give isl_space *Scop::getParamSpace() const {
891   return isl_set_get_space(this->Context);
892 }
893 
894 __isl_give isl_set *Scop::getAssumedContext() const {
895   return isl_set_copy(AssumedContext);
896 }
897 
898 void Scop::printContext(raw_ostream &OS) const {
899   OS << "Context:\n";
900 
901   if (!Context) {
902     OS.indent(4) << "n/a\n\n";
903     return;
904   }
905 
906   OS.indent(4) << getContextStr() << "\n";
907 
908   for (ParamVecType::const_iterator PI = Parameters.begin(),
909                                     PE = Parameters.end();
910        PI != PE; ++PI) {
911     const SCEV *Parameter = *PI;
912     int Dim = ParameterIds.find(Parameter)->second;
913 
914     OS.indent(4) << "p" << Dim << ": " << *Parameter << "\n";
915   }
916 }
917 
918 void Scop::printStatements(raw_ostream &OS) const {
919   OS << "Statements {\n";
920 
921   for (const_iterator SI = begin(), SE = end(); SI != SE; ++SI)
922     OS.indent(4) << (**SI);
923 
924   OS.indent(4) << "}\n";
925 }
926 
927 void Scop::print(raw_ostream &OS) const {
928   printContext(OS.indent(4));
929   printStatements(OS.indent(4));
930 }
931 
932 void Scop::dump() const { print(dbgs()); }
933 
934 isl_ctx *Scop::getIslCtx() const { return IslCtx; }
935 
936 __isl_give isl_union_set *Scop::getDomains() {
937   isl_union_set *Domain = NULL;
938 
939   for (Scop::iterator SI = begin(), SE = end(); SI != SE; ++SI)
940     if (!Domain)
941       Domain = isl_union_set_from_set((*SI)->getDomain());
942     else
943       Domain = isl_union_set_union(Domain,
944                                    isl_union_set_from_set((*SI)->getDomain()));
945 
946   return Domain;
947 }
948 
949 ScalarEvolution *Scop::getSE() const { return SE; }
950 
951 bool Scop::isTrivialBB(BasicBlock *BB, TempScop &tempScop) {
952   if (tempScop.getAccessFunctions(BB))
953     return false;
954 
955   return true;
956 }
957 
958 void Scop::buildScop(TempScop &tempScop, const Region &CurRegion,
959                      SmallVectorImpl<Loop *> &NestLoops,
960                      SmallVectorImpl<unsigned> &Scatter, LoopInfo &LI) {
961   Loop *L = castToLoop(CurRegion, LI);
962 
963   if (L)
964     NestLoops.push_back(L);
965 
966   unsigned loopDepth = NestLoops.size();
967   assert(Scatter.size() > loopDepth && "Scatter not big enough!");
968 
969   for (Region::const_element_iterator I = CurRegion.element_begin(),
970                                       E = CurRegion.element_end();
971        I != E; ++I)
972     if (I->isSubRegion())
973       buildScop(tempScop, *(I->getNodeAs<Region>()), NestLoops, Scatter, LI);
974     else {
975       BasicBlock *BB = I->getNodeAs<BasicBlock>();
976 
977       if (isTrivialBB(BB, tempScop))
978         continue;
979 
980       Stmts.push_back(
981           new ScopStmt(*this, tempScop, CurRegion, *BB, NestLoops, Scatter));
982 
983       // Increasing the Scattering function is OK for the moment, because
984       // we are using a depth first iterator and the program is well structured.
985       ++Scatter[loopDepth];
986     }
987 
988   if (!L)
989     return;
990 
991   // Exiting a loop region.
992   Scatter[loopDepth] = 0;
993   NestLoops.pop_back();
994   ++Scatter[loopDepth - 1];
995 }
996 
997 //===----------------------------------------------------------------------===//
998 ScopInfo::ScopInfo() : RegionPass(ID), scop(0) {
999   ctx = isl_ctx_alloc();
1000   isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
1001 }
1002 
1003 ScopInfo::~ScopInfo() {
1004   clear();
1005   isl_ctx_free(ctx);
1006 }
1007 
1008 void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
1009   AU.addRequired<LoopInfo>();
1010   AU.addRequired<RegionInfo>();
1011   AU.addRequired<ScalarEvolution>();
1012   AU.addRequired<TempScopInfo>();
1013   AU.setPreservesAll();
1014 }
1015 
1016 bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
1017   LoopInfo &LI = getAnalysis<LoopInfo>();
1018   ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
1019 
1020   TempScop *tempScop = getAnalysis<TempScopInfo>().getTempScop(R);
1021 
1022   // This region is no Scop.
1023   if (!tempScop) {
1024     scop = 0;
1025     return false;
1026   }
1027 
1028   // Statistics.
1029   ++ScopFound;
1030   if (tempScop->getMaxLoopDepth() > 0)
1031     ++RichScopFound;
1032 
1033   scop = new Scop(*tempScop, LI, SE, ctx);
1034 
1035   return false;
1036 }
1037 
1038 char ScopInfo::ID = 0;
1039 
1040 Pass *polly::createScopInfoPass() { return new ScopInfo(); }
1041 
1042 INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops",
1043                       "Polly - Create polyhedral description of Scops", false,
1044                       false);
1045 INITIALIZE_PASS_DEPENDENCY(LoopInfo);
1046 INITIALIZE_PASS_DEPENDENCY(RegionInfo);
1047 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
1048 INITIALIZE_PASS_DEPENDENCY(TempScopInfo);
1049 INITIALIZE_PASS_END(ScopInfo, "polly-scops",
1050                     "Polly - Create polyhedral description of Scops", false,
1051                     false)
1052