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