1 //===--------- SCEVAffinator.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 SCEV value.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "polly/Support/SCEVAffinator.h"
15 #include "polly/ScopInfo.h"
16 #include "polly/Support/GICHelper.h"
17 #include "polly/Support/SCEVValidator.h"
18 #include "polly/Support/ScopHelper.h"
19 #include "isl/aff.h"
20 #include "isl/local_space.h"
21 #include "isl/set.h"
22 #include "isl/val.h"
23 
24 using namespace llvm;
25 using namespace polly;
26 
27 // The maximal number of basic sets we allow during the construction of a
28 // piecewise affine function. More complex ones will result in very high
29 // compile time.
30 static int const MaxConjunctsInPwAff = 100;
31 
32 /// @brief Add the number of basic sets in @p Domain to @p User
33 static isl_stat addNumBasicSets(isl_set *Domain, isl_aff *Aff, void *User) {
34   auto *NumBasicSets = static_cast<unsigned *>(User);
35   *NumBasicSets += isl_set_n_basic_set(Domain);
36   isl_set_free(Domain);
37   isl_aff_free(Aff);
38   return isl_stat_ok;
39 }
40 
41 /// @brief Determine if @p PWA is to complex to continue
42 ///
43 /// Note that @p PWA will be "free" (deallocated) if this function returns true,
44 /// but not if this function returns false.
45 static bool isToComplex(isl_pw_aff *PWA) {
46   unsigned NumBasicSets = 0;
47   isl_pw_aff_foreach_piece(PWA, addNumBasicSets, &NumBasicSets);
48   if (NumBasicSets <= MaxConjunctsInPwAff)
49     return false;
50   isl_pw_aff_free(PWA);
51   return true;
52 }
53 
54 SCEVAffinator::SCEVAffinator(Scop *S, LoopInfo &LI)
55     : S(S), Ctx(S->getIslCtx()), R(S->getRegion()), SE(*S->getSE()), LI(LI),
56       TD(R.getEntry()->getParent()->getParent()->getDataLayout()) {}
57 
58 SCEVAffinator::~SCEVAffinator() {
59   for (const auto &CachedPair : CachedExpressions)
60     isl_pw_aff_free(CachedPair.second);
61 }
62 
63 __isl_give isl_pw_aff *SCEVAffinator::getPwAff(const SCEV *Expr,
64                                                BasicBlock *BB) {
65   this->BB = BB;
66 
67   if (BB) {
68     auto *DC = S->getDomainConditions(BB);
69     NumIterators = isl_set_n_dim(DC);
70     isl_set_free(DC);
71   } else
72     NumIterators = 0;
73 
74   auto *Scope = LI.getLoopFor(BB);
75   S->addParams(getParamsInAffineExpr(&R, Scope, Expr, SE));
76 
77   return visit(Expr);
78 }
79 
80 __isl_give isl_set *
81 SCEVAffinator::getWrappingContext(SCEV::NoWrapFlags Flags, Type *ExprType,
82                                   __isl_keep isl_pw_aff *PWA,
83                                   __isl_take isl_set *ExprDomain) const {
84   // If the SCEV flags do contain NSW (no signed wrap) then PWA already
85   // represents Expr in modulo semantic (it is not allowed to overflow), thus we
86   // are done. Otherwise, we will compute:
87   //   PWA = ((PWA + 2^(n-1)) mod (2 ^ n)) - 2^(n-1)
88   // whereas n is the number of bits of the Expr, hence:
89   //   n = bitwidth(ExprType)
90 
91   if (Flags & SCEV::FlagNSW)
92     return nullptr;
93 
94   isl_pw_aff *PWAMod = addModuloSemantic(isl_pw_aff_copy(PWA), ExprType);
95   if (isl_pw_aff_is_equal(PWA, PWAMod)) {
96     isl_pw_aff_free(PWAMod);
97     return nullptr;
98   }
99 
100   PWA = isl_pw_aff_copy(PWA);
101 
102   auto *NotEqualSet = isl_pw_aff_ne_set(PWA, PWAMod);
103   NotEqualSet = isl_set_intersect(NotEqualSet, isl_set_copy(ExprDomain));
104   NotEqualSet = isl_set_gist_params(NotEqualSet, S->getContext());
105   NotEqualSet = isl_set_params(NotEqualSet);
106   return NotEqualSet;
107 }
108 
109 __isl_give isl_set *SCEVAffinator::getWrappingContext() const {
110 
111   isl_set *WrappingCtx = isl_set_empty(S->getParamSpace());
112 
113   for (const auto &CachedPair : CachedExpressions) {
114     const SCEV *Expr = CachedPair.first.first;
115     SCEV::NoWrapFlags Flags;
116 
117     switch (Expr->getSCEVType()) {
118     case scAddExpr:
119       Flags = cast<SCEVAddExpr>(Expr)->getNoWrapFlags();
120       break;
121     case scMulExpr:
122       Flags = cast<SCEVMulExpr>(Expr)->getNoWrapFlags();
123       break;
124     case scAddRecExpr:
125       Flags = cast<SCEVAddRecExpr>(Expr)->getNoWrapFlags();
126       break;
127     default:
128       continue;
129     }
130 
131     isl_pw_aff *PWA = CachedPair.second;
132     BasicBlock *BB = CachedPair.first.second;
133     isl_set *ExprDomain = BB ? S->getDomainConditions(BB) : nullptr;
134 
135     isl_set *WPWACtx =
136         getWrappingContext(Flags, Expr->getType(), PWA, ExprDomain);
137     isl_set_free(ExprDomain);
138 
139     WrappingCtx = WPWACtx ? isl_set_union(WrappingCtx, WPWACtx) : WrappingCtx;
140   }
141 
142   return WrappingCtx;
143 }
144 
145 __isl_give isl_pw_aff *
146 SCEVAffinator::addModuloSemantic(__isl_take isl_pw_aff *PWA,
147                                  Type *ExprType) const {
148   unsigned Width = TD.getTypeStoreSizeInBits(ExprType);
149   isl_ctx *Ctx = isl_pw_aff_get_ctx(PWA);
150 
151   isl_val *ModVal = isl_val_int_from_ui(Ctx, Width);
152   ModVal = isl_val_2exp(ModVal);
153 
154   isl_val *AddVal = isl_val_int_from_ui(Ctx, Width - 1);
155   AddVal = isl_val_2exp(AddVal);
156 
157   isl_set *Domain = isl_pw_aff_domain(isl_pw_aff_copy(PWA));
158 
159   isl_pw_aff *AddPW = isl_pw_aff_val_on_domain(Domain, AddVal);
160 
161   PWA = isl_pw_aff_add(PWA, isl_pw_aff_copy(AddPW));
162   PWA = isl_pw_aff_mod_val(PWA, ModVal);
163   PWA = isl_pw_aff_sub(PWA, AddPW);
164 
165   return PWA;
166 }
167 
168 bool SCEVAffinator::hasNSWAddRecForLoop(Loop *L) const {
169   for (const auto &CachedPair : CachedExpressions) {
170     auto *AddRec = dyn_cast<SCEVAddRecExpr>(CachedPair.first.first);
171     if (!AddRec)
172       continue;
173     if (AddRec->getLoop() != L)
174       continue;
175     if (AddRec->getNoWrapFlags() & SCEV::FlagNSW)
176       return true;
177   }
178 
179   return false;
180 }
181 
182 __isl_give isl_pw_aff *SCEVAffinator::visit(const SCEV *Expr) {
183 
184   auto Key = std::make_pair(Expr, BB);
185   isl_pw_aff *PWA = CachedExpressions[Key];
186   if (PWA)
187     return isl_pw_aff_copy(PWA);
188 
189   auto ConstantAndLeftOverPair = extractConstantFactor(Expr, *S->getSE());
190   auto *Factor = ConstantAndLeftOverPair.first;
191   Expr = ConstantAndLeftOverPair.second;
192 
193   // In case the scev is a valid parameter, we do not further analyze this
194   // expression, but create a new parameter in the isl_pw_aff. This allows us
195   // to treat subexpressions that we cannot translate into an piecewise affine
196   // expression, as constant parameters of the piecewise affine expression.
197   if (isl_id *Id = S->getIdForParam(Expr)) {
198     isl_space *Space = isl_space_set_alloc(Ctx, 1, NumIterators);
199     Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
200 
201     isl_set *Domain = isl_set_universe(isl_space_copy(Space));
202     isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space));
203     Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
204 
205     PWA = isl_pw_aff_alloc(Domain, Affine);
206   } else {
207     PWA = SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Expr);
208   }
209 
210   PWA = isl_pw_aff_mul(visitConstant(Factor), PWA);
211 
212   // For compile time reasons we need to simplify the PWA before we cache and
213   // return it.
214   PWA = isl_pw_aff_coalesce(PWA);
215   CachedExpressions[Key] = isl_pw_aff_copy(PWA);
216   return PWA;
217 }
218 
219 __isl_give isl_pw_aff *SCEVAffinator::visitConstant(const SCEVConstant *Expr) {
220   ConstantInt *Value = Expr->getValue();
221   isl_val *v;
222 
223   // LLVM does not define if an integer value is interpreted as a signed or
224   // unsigned value. Hence, without further information, it is unknown how
225   // this value needs to be converted to GMP. At the moment, we only support
226   // signed operations. So we just interpret it as signed. Later, there are
227   // two options:
228   //
229   // 1. We always interpret any value as signed and convert the values on
230   //    demand.
231   // 2. We pass down the signedness of the calculation and use it to interpret
232   //    this constant correctly.
233   v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
234 
235   isl_space *Space = isl_space_set_alloc(Ctx, 0, NumIterators);
236   isl_local_space *ls = isl_local_space_from_space(Space);
237   return isl_pw_aff_from_aff(isl_aff_val_on_domain(ls, v));
238 }
239 
240 __isl_give isl_pw_aff *
241 SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
242   llvm_unreachable("SCEVTruncateExpr not yet supported");
243 }
244 
245 __isl_give isl_pw_aff *
246 SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
247   llvm_unreachable("SCEVZeroExtendExpr not yet supported");
248 }
249 
250 __isl_give isl_pw_aff *
251 SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
252   // Assuming the value is signed, a sign extension is basically a noop.
253   // TODO: Reconsider this as soon as we support unsigned values.
254   return visit(Expr->getOperand());
255 }
256 
257 __isl_give isl_pw_aff *SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
258   isl_pw_aff *Sum = visit(Expr->getOperand(0));
259 
260   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
261     isl_pw_aff *NextSummand = visit(Expr->getOperand(i));
262     Sum = isl_pw_aff_add(Sum, NextSummand);
263     if (isToComplex(Sum))
264       return nullptr;
265   }
266 
267   return Sum;
268 }
269 
270 __isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) {
271   llvm_unreachable("SCEVMulExpr should not be reached");
272 }
273 
274 __isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) {
275   llvm_unreachable("SCEVUDivExpr not yet supported");
276 }
277 
278 __isl_give isl_pw_aff *
279 SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
280   assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
281 
282   auto Flags = Expr->getNoWrapFlags();
283 
284   // Directly generate isl_pw_aff for Expr if 'start' is zero.
285   if (Expr->getStart()->isZero()) {
286     assert(S->getRegion().contains(Expr->getLoop()) &&
287            "Scop does not contain the loop referenced in this AddRec");
288 
289     isl_pw_aff *Step = visit(Expr->getOperand(1));
290     isl_space *Space = isl_space_set_alloc(Ctx, 0, NumIterators);
291     isl_local_space *LocalSpace = isl_local_space_from_space(Space);
292 
293     unsigned loopDimension = S->getRelativeLoopDepth(Expr->getLoop());
294 
295     isl_aff *LAff = isl_aff_set_coefficient_si(
296         isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
297     isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
298 
299     return isl_pw_aff_mul(Step, LPwAff);
300   }
301 
302   // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
303   // if 'start' is not zero.
304   // TODO: Using the original SCEV no-wrap flags is not always safe, however
305   //       as our code generation is reordering the expression anyway it doesn't
306   //       really matter.
307   ScalarEvolution &SE = *S->getSE();
308   const SCEV *ZeroStartExpr =
309       SE.getAddRecExpr(SE.getConstant(Expr->getStart()->getType(), 0),
310                        Expr->getStepRecurrence(SE), Expr->getLoop(), Flags);
311 
312   isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr);
313   isl_pw_aff *Start = visit(Expr->getStart());
314 
315   return isl_pw_aff_add(ZeroStartResult, Start);
316 }
317 
318 __isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) {
319   isl_pw_aff *Max = visit(Expr->getOperand(0));
320 
321   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
322     isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
323     Max = isl_pw_aff_max(Max, NextOperand);
324     if (isToComplex(Max))
325       return nullptr;
326   }
327 
328   return Max;
329 }
330 
331 __isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) {
332   llvm_unreachable("SCEVUMaxExpr not yet supported");
333 }
334 
335 __isl_give isl_pw_aff *SCEVAffinator::visitSDivInstruction(Instruction *SDiv) {
336   assert(SDiv->getOpcode() == Instruction::SDiv && "Assumed SDiv instruction!");
337   auto *SE = S->getSE();
338 
339   auto *Divisor = SDiv->getOperand(1);
340   auto *DivisorSCEV = SE->getSCEV(Divisor);
341   auto *DivisorPWA = visit(DivisorSCEV);
342   assert(isa<ConstantInt>(Divisor) &&
343          "SDiv is no parameter but has a non-constant RHS.");
344 
345   auto *Dividend = SDiv->getOperand(0);
346   auto *DividendSCEV = SE->getSCEV(Dividend);
347   auto *DividendPWA = visit(DividendSCEV);
348   return isl_pw_aff_tdiv_q(DividendPWA, DivisorPWA);
349 }
350 
351 __isl_give isl_pw_aff *SCEVAffinator::visitSRemInstruction(Instruction *SRem) {
352   assert(SRem->getOpcode() == Instruction::SRem && "Assumed SRem instruction!");
353   auto *SE = S->getSE();
354 
355   auto *Divisor = dyn_cast<ConstantInt>(SRem->getOperand(1));
356   assert(Divisor && "SRem is no parameter but has a non-constant RHS.");
357   auto *DivisorVal = isl_valFromAPInt(Ctx, Divisor->getValue(),
358                                       /* isSigned */ true);
359 
360   auto *Dividend = SRem->getOperand(0);
361   auto *DividendSCEV = SE->getSCEV(Dividend);
362   auto *DividendPWA = visit(DividendSCEV);
363 
364   return isl_pw_aff_mod_val(DividendPWA, isl_val_abs(DivisorVal));
365 }
366 
367 __isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) {
368   if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) {
369     switch (I->getOpcode()) {
370     case Instruction::SDiv:
371       return visitSDivInstruction(I);
372     case Instruction::SRem:
373       return visitSRemInstruction(I);
374     default:
375       break; // Fall through.
376     }
377   }
378 
379   llvm_unreachable(
380       "Unknowns SCEV was neither parameter nor a valid instruction.");
381 }
382