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