1 //===------ IslExprBuilder.cpp ----- Code generate isl AST expressions ----===//
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 //===----------------------------------------------------------------------===//
11 
12 #include "polly/CodeGen/IslExprBuilder.h"
13 #include "polly/Options.h"
14 #include "polly/ScopInfo.h"
15 #include "polly/Support/GICHelper.h"
16 #include "polly/Support/ScopHelper.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
19 
20 using namespace llvm;
21 using namespace polly;
22 
23 /// @brief Different overflow tracking modes.
24 enum OverflowTrackingChoice {
25   OT_NEVER,   ///< Never tack potential overflows.
26   OT_REQUEST, ///< Track potential overflows if requested.
27   OT_ALWAYS   ///< Always track potential overflows.
28 };
29 
30 static cl::opt<OverflowTrackingChoice> OTMode(
31     "polly-overflow-tracking",
32     cl::desc("Define where potential integer overflows in generated "
33              "expressions should be tracked."),
34     cl::values(clEnumValN(OT_NEVER, "never", "Never track the overflow bit."),
35                clEnumValN(OT_REQUEST, "request",
36                           "Track the overflow bit if requested."),
37                clEnumValN(OT_ALWAYS, "always",
38                           "Always track the overflow bit."),
39                clEnumValEnd),
40     cl::Hidden, cl::init(OT_REQUEST), cl::ZeroOrMore, cl::cat(PollyCategory));
41 
42 IslExprBuilder::IslExprBuilder(Scop &S, PollyIRBuilder &Builder,
43                                IDToValueTy &IDToValue, ValueMapT &GlobalMap,
44                                const DataLayout &DL, ScalarEvolution &SE,
45                                DominatorTree &DT, LoopInfo &LI)
46     : S(S), Builder(Builder), IDToValue(IDToValue), GlobalMap(GlobalMap),
47       DL(DL), SE(SE), DT(DT), LI(LI) {
48   OverflowState = (OTMode == OT_ALWAYS) ? Builder.getFalse() : nullptr;
49 }
50 
51 void IslExprBuilder::setTrackOverflow(bool Enable) {
52   // If potential overflows are tracked always or never we ignore requests
53   // to change the behaviour.
54   if (OTMode != OT_REQUEST)
55     return;
56 
57   if (Enable) {
58     // If tracking should be enabled initialize the OverflowState.
59     OverflowState = Builder.getFalse();
60   } else {
61     // If tracking should be disabled just unset the OverflowState.
62     OverflowState = nullptr;
63   }
64 }
65 
66 Value *IslExprBuilder::getOverflowState() const {
67   // If the overflow tracking was requested but it is disabled we avoid the
68   // additional nullptr checks at the call sides but instead provide a
69   // meaningful result.
70   if (OTMode == OT_NEVER)
71     return Builder.getFalse();
72   return OverflowState;
73 }
74 
75 Value *IslExprBuilder::createBinOp(BinaryOperator::BinaryOps Opc, Value *LHS,
76                                    Value *RHS, const Twine &Name) {
77   // @TODO Temporarily promote types of potentially overflowing binary
78   //       operations to at least i64.
79   Value *I64C = Builder.getInt64(0);
80   unifyTypes(LHS, RHS, I64C);
81 
82   // Handle the plain operation (without overflow tracking) first.
83   if (!OverflowState) {
84     switch (Opc) {
85     case Instruction::Add:
86       return Builder.CreateNSWAdd(LHS, RHS, Name);
87     case Instruction::Sub:
88       return Builder.CreateNSWSub(LHS, RHS, Name);
89     case Instruction::Mul:
90       return Builder.CreateNSWMul(LHS, RHS, Name);
91     default:
92       llvm_unreachable("Unknown binary operator!");
93     }
94   }
95 
96   Function *F = nullptr;
97   Module *M = Builder.GetInsertBlock()->getModule();
98   switch (Opc) {
99   case Instruction::Add:
100     F = Intrinsic::getDeclaration(M, Intrinsic::sadd_with_overflow,
101                                   {LHS->getType()});
102     break;
103   case Instruction::Sub:
104     F = Intrinsic::getDeclaration(M, Intrinsic::ssub_with_overflow,
105                                   {LHS->getType()});
106     break;
107   case Instruction::Mul:
108     F = Intrinsic::getDeclaration(M, Intrinsic::smul_with_overflow,
109                                   {LHS->getType()});
110     break;
111   default:
112     llvm_unreachable("No overflow intrinsic for binary operator found!");
113   }
114 
115   auto *ResultStruct = Builder.CreateCall(F, {LHS, RHS}, Name);
116   assert(ResultStruct->getType()->isStructTy());
117 
118   auto *OverflowFlag =
119       Builder.CreateExtractValue(ResultStruct, 1, Name + ".obit");
120 
121   // If all overflows are tracked we do not combine the results as this could
122   // cause dominance problems. Instead we will always keep the last overflow
123   // flag as current state.
124   if (OTMode == OT_ALWAYS)
125     OverflowState = OverflowFlag;
126   else
127     OverflowState =
128         Builder.CreateOr(OverflowState, OverflowFlag, "polly.overflow.state");
129 
130   return Builder.CreateExtractValue(ResultStruct, 0, Name + ".res");
131 }
132 
133 Value *IslExprBuilder::createAdd(Value *LHS, Value *RHS, const Twine &Name) {
134   return createBinOp(Instruction::Add, LHS, RHS, Name);
135 }
136 
137 Value *IslExprBuilder::createSub(Value *LHS, Value *RHS, const Twine &Name) {
138   return createBinOp(Instruction::Sub, LHS, RHS, Name);
139 }
140 
141 Value *IslExprBuilder::createMul(Value *LHS, Value *RHS, const Twine &Name) {
142   return createBinOp(Instruction::Mul, LHS, RHS, Name);
143 }
144 
145 static Type *getWidestType(Type *T1, Type *T2) {
146   assert(isa<IntegerType>(T1) && isa<IntegerType>(T2));
147 
148   if (T1->getPrimitiveSizeInBits() < T2->getPrimitiveSizeInBits())
149     return T2;
150   else
151     return T1;
152 }
153 
154 void IslExprBuilder::unifyTypes(Value *&V0, Value *&V1, Value *&V2) {
155   auto *T0 = V0->getType();
156   auto *T1 = V1->getType();
157   auto *T2 = V2->getType();
158   if (T0 == T1 && T1 == T2)
159     return;
160   auto *MaxT = getWidestType(T0, T1);
161   MaxT = getWidestType(MaxT, T2);
162   V0 = Builder.CreateSExt(V0, MaxT);
163   V1 = Builder.CreateSExt(V1, MaxT);
164   V2 = Builder.CreateSExt(V2, MaxT);
165 }
166 
167 Value *IslExprBuilder::createOpUnary(__isl_take isl_ast_expr *Expr) {
168   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_minus &&
169          "Unsupported unary operation");
170 
171   auto *V = create(isl_ast_expr_get_op_arg(Expr, 0));
172   assert(V->getType()->isIntegerTy() &&
173          "Unary expressions can only be created for integer types");
174 
175   isl_ast_expr_free(Expr);
176   return createSub(ConstantInt::getNullValue(V->getType()), V);
177 }
178 
179 Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
180   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
181          "isl ast expression not of type isl_ast_op");
182   assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
183          "We need at least two operands in an n-ary operation");
184   assert((isl_ast_expr_get_op_type(Expr) == isl_ast_op_max ||
185           isl_ast_expr_get_op_type(Expr) == isl_ast_op_min) &&
186          "This is no n-ary isl ast expression");
187 
188   bool IsMax = isl_ast_expr_get_op_type(Expr) == isl_ast_op_max;
189   auto Pred = IsMax ? CmpInst::ICMP_SGT : CmpInst::ICMP_SLT;
190   auto *V = create(isl_ast_expr_get_op_arg(Expr, 0));
191 
192   for (int i = 1; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
193     auto *OpV = create(isl_ast_expr_get_op_arg(Expr, i));
194     unifyTypes(V, OpV);
195     V = Builder.CreateSelect(Builder.CreateICmp(Pred, V, OpV), V, OpV);
196   }
197 
198   // TODO: We can truncate the result, if it fits into a smaller type. This can
199   // help in cases where we have larger operands (e.g. i67) but the result is
200   // known to fit into i64. Without the truncation, the larger i67 type may
201   // force all subsequent operations to be performed on a non-native type.
202   isl_ast_expr_free(Expr);
203   return V;
204 }
205 
206 Value *IslExprBuilder::createAccessAddress(isl_ast_expr *Expr) {
207   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
208          "isl ast expression not of type isl_ast_op");
209   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_access &&
210          "not an access isl ast expression");
211   assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
212          "We need at least two operands to create a member access.");
213 
214   Value *Base, *IndexOp, *Access;
215   isl_ast_expr *BaseExpr;
216   isl_id *BaseId;
217 
218   BaseExpr = isl_ast_expr_get_op_arg(Expr, 0);
219   BaseId = isl_ast_expr_get_id(BaseExpr);
220   isl_ast_expr_free(BaseExpr);
221 
222   const ScopArrayInfo *SAI = ScopArrayInfo::getFromId(BaseId);
223   Base = SAI->getBasePtr();
224 
225   if (auto NewBase = GlobalMap.lookup(Base))
226     Base = NewBase;
227 
228   assert(Base->getType()->isPointerTy() && "Access base should be a pointer");
229   StringRef BaseName = Base->getName();
230 
231   auto PointerTy = PointerType::get(SAI->getElementType(),
232                                     Base->getType()->getPointerAddressSpace());
233   if (Base->getType() != PointerTy) {
234     Base =
235         Builder.CreateBitCast(Base, PointerTy, "polly.access.cast." + BaseName);
236   }
237 
238   IndexOp = nullptr;
239   for (unsigned u = 1, e = isl_ast_expr_get_op_n_arg(Expr); u < e; u++) {
240     Value *NextIndex = create(isl_ast_expr_get_op_arg(Expr, u));
241     assert(NextIndex->getType()->isIntegerTy() &&
242            "Access index should be an integer");
243 
244     IndexOp = !IndexOp ? NextIndex : createAdd(IndexOp, NextIndex,
245                                                "polly.access.add." + BaseName);
246 
247     // For every but the last dimension multiply the size, for the last
248     // dimension we can exit the loop.
249     if (u + 1 >= e)
250       break;
251 
252     const SCEV *DimSCEV = SAI->getDimensionSize(u);
253 
254     llvm::ValueToValueMap Map(GlobalMap.begin(), GlobalMap.end());
255     DimSCEV = SCEVParameterRewriter::rewrite(DimSCEV, SE, Map);
256     Value *DimSize =
257         expandCodeFor(S, SE, DL, "polly", DimSCEV, DimSCEV->getType(),
258                       &*Builder.GetInsertPoint());
259 
260     IndexOp = createMul(IndexOp, DimSize, "polly.access.mul." + BaseName);
261   }
262 
263   Access = Builder.CreateGEP(Base, IndexOp, "polly.access." + BaseName);
264 
265   isl_ast_expr_free(Expr);
266   return Access;
267 }
268 
269 Value *IslExprBuilder::createOpAccess(isl_ast_expr *Expr) {
270   Value *Addr = createAccessAddress(Expr);
271   assert(Addr && "Could not create op access address");
272   return Builder.CreateLoad(Addr, Addr->getName() + ".load");
273 }
274 
275 Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) {
276   Value *LHS, *RHS, *Res;
277   isl_ast_op_type OpType;
278 
279   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
280          "isl ast expression not of type isl_ast_op");
281   assert(isl_ast_expr_get_op_n_arg(Expr) == 2 &&
282          "not a binary isl ast expression");
283 
284   OpType = isl_ast_expr_get_op_type(Expr);
285 
286   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
287   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
288 
289   // For possibly overflowing operations we will later adjust types but
290   // for others we do it now as we will directly create the operations.
291   switch (OpType) {
292   case isl_ast_op_pdiv_q:
293   case isl_ast_op_pdiv_r:
294   case isl_ast_op_div:
295   case isl_ast_op_fdiv_q:
296   case isl_ast_op_zdiv_r:
297     unifyTypes(LHS, RHS);
298     break;
299   case isl_ast_op_add:
300   case isl_ast_op_sub:
301   case isl_ast_op_mul:
302     // Do nothing
303     break;
304   default:
305     llvm_unreachable("This is no binary isl ast expression");
306   }
307 
308   switch (OpType) {
309   default:
310     llvm_unreachable("This is no binary isl ast expression");
311   case isl_ast_op_add:
312     Res = createAdd(LHS, RHS);
313     break;
314   case isl_ast_op_sub:
315     Res = createSub(LHS, RHS);
316     break;
317   case isl_ast_op_mul:
318     Res = createMul(LHS, RHS);
319     break;
320   case isl_ast_op_div:
321     Res = Builder.CreateSDiv(LHS, RHS, "pexp.div", true);
322     break;
323   case isl_ast_op_pdiv_q: // Dividend is non-negative
324     Res = Builder.CreateUDiv(LHS, RHS, "pexp.p_div_q");
325     break;
326   case isl_ast_op_fdiv_q: { // Round towards -infty
327     if (auto *Const = dyn_cast<ConstantInt>(RHS)) {
328       auto &Val = Const->getValue();
329       if (Val.isPowerOf2() && Val.isNonNegative()) {
330         Res = Builder.CreateAShr(LHS, Val.ceilLogBase2(), "polly.fdiv_q.shr");
331         break;
332       }
333     }
334     // TODO: Review code and check that this calculation does not yield
335     //       incorrect overflow in some bordercases.
336     //
337     // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
338     Value *Sum1 = createSub(LHS, RHS, "pexp.fdiv_q.0");
339     Value *One = ConstantInt::get(Sum1->getType(), 1);
340     Value *Sum2 = createAdd(Sum1, One, "pexp.fdiv_q.1");
341     Value *Zero = ConstantInt::get(LHS->getType(), 0);
342     Value *isNegative = Builder.CreateICmpSLT(LHS, Zero, "pexp.fdiv_q.2");
343     unifyTypes(LHS, Sum2);
344     Value *Dividend =
345         Builder.CreateSelect(isNegative, Sum2, LHS, "pexp.fdiv_q.3");
346     unifyTypes(Dividend, RHS);
347     Res = Builder.CreateSDiv(Dividend, RHS, "pexp.fdiv_q.4");
348     break;
349   }
350   case isl_ast_op_pdiv_r: // Dividend is non-negative
351     Res = Builder.CreateURem(LHS, RHS, "pexp.pdiv_r");
352     break;
353 
354   case isl_ast_op_zdiv_r: // Result only compared against zero
355     Res = Builder.CreateSRem(LHS, RHS, "pexp.zdiv_r");
356     break;
357   }
358 
359   // TODO: We can truncate the result, if it fits into a smaller type. This can
360   // help in cases where we have larger operands (e.g. i67) but the result is
361   // known to fit into i64. Without the truncation, the larger i67 type may
362   // force all subsequent operations to be performed on a non-native type.
363   isl_ast_expr_free(Expr);
364   return Res;
365 }
366 
367 Value *IslExprBuilder::createOpSelect(__isl_take isl_ast_expr *Expr) {
368   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_select &&
369          "Unsupported unary isl ast expression");
370   Value *LHS, *RHS, *Cond;
371 
372   Cond = create(isl_ast_expr_get_op_arg(Expr, 0));
373   if (!Cond->getType()->isIntegerTy(1))
374     Cond = Builder.CreateIsNotNull(Cond);
375 
376   LHS = create(isl_ast_expr_get_op_arg(Expr, 1));
377   RHS = create(isl_ast_expr_get_op_arg(Expr, 2));
378   unifyTypes(LHS, RHS);
379 
380   isl_ast_expr_free(Expr);
381   return Builder.CreateSelect(Cond, LHS, RHS);
382 }
383 
384 Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) {
385   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
386          "Expected an isl_ast_expr_op expression");
387 
388   Value *LHS, *RHS, *Res;
389 
390   auto *Op0 = isl_ast_expr_get_op_arg(Expr, 0);
391   auto *Op1 = isl_ast_expr_get_op_arg(Expr, 1);
392   bool HasNonAddressOfOperand =
393       isl_ast_expr_get_type(Op0) != isl_ast_expr_op ||
394       isl_ast_expr_get_type(Op1) != isl_ast_expr_op ||
395       isl_ast_expr_get_op_type(Op0) != isl_ast_op_address_of ||
396       isl_ast_expr_get_op_type(Op1) != isl_ast_op_address_of;
397 
398   LHS = create(Op0);
399   RHS = create(Op1);
400 
401   auto *LHSTy = LHS->getType();
402   auto *RHSTy = RHS->getType();
403   bool IsPtrType = LHSTy->isPointerTy() || RHSTy->isPointerTy();
404   bool UseUnsignedCmp = IsPtrType && !HasNonAddressOfOperand;
405 
406   auto *PtrAsIntTy = Builder.getIntNTy(DL.getPointerSizeInBits());
407   if (LHSTy->isPointerTy())
408     LHS = Builder.CreatePtrToInt(LHS, PtrAsIntTy);
409   if (RHSTy->isPointerTy())
410     RHS = Builder.CreatePtrToInt(RHS, PtrAsIntTy);
411 
412   unifyTypes(LHS, RHS);
413 
414   isl_ast_op_type OpType = isl_ast_expr_get_op_type(Expr);
415   assert(OpType >= isl_ast_op_eq && OpType <= isl_ast_op_gt &&
416          "Unsupported ICmp isl ast expression");
417   assert(isl_ast_op_eq + 4 == isl_ast_op_gt &&
418          "Isl ast op type interface changed");
419 
420   CmpInst::Predicate Predicates[5][2] = {
421       {CmpInst::ICMP_EQ, CmpInst::ICMP_EQ},
422       {CmpInst::ICMP_SLE, CmpInst::ICMP_ULE},
423       {CmpInst::ICMP_SLT, CmpInst::ICMP_ULT},
424       {CmpInst::ICMP_SGE, CmpInst::ICMP_UGE},
425       {CmpInst::ICMP_SGT, CmpInst::ICMP_UGT},
426   };
427 
428   Res = Builder.CreateICmp(Predicates[OpType - isl_ast_op_eq][UseUnsignedCmp],
429                            LHS, RHS);
430 
431   isl_ast_expr_free(Expr);
432   return Res;
433 }
434 
435 Value *IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr *Expr) {
436   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
437          "Expected an isl_ast_expr_op expression");
438 
439   Value *LHS, *RHS, *Res;
440   isl_ast_op_type OpType;
441 
442   OpType = isl_ast_expr_get_op_type(Expr);
443 
444   assert((OpType == isl_ast_op_and || OpType == isl_ast_op_or) &&
445          "Unsupported isl_ast_op_type");
446 
447   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
448   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
449 
450   // Even though the isl pretty printer prints the expressions as 'exp && exp'
451   // or 'exp || exp', we actually code generate the bitwise expressions
452   // 'exp & exp' or 'exp | exp'. This forces the evaluation of both branches,
453   // but it is, due to the use of i1 types, otherwise equivalent. The reason
454   // to go for bitwise operations is, that we assume the reduced control flow
455   // will outweight the overhead introduced by evaluating unneeded expressions.
456   // The isl code generation currently does not take advantage of the fact that
457   // the expression after an '||' or '&&' is in some cases not evaluated.
458   // Evaluating it anyways does not cause any undefined behaviour.
459   //
460   // TODO: Document in isl itself, that the unconditionally evaluating the
461   // second part of '||' or '&&' expressions is safe.
462   if (!LHS->getType()->isIntegerTy(1))
463     LHS = Builder.CreateIsNotNull(LHS);
464   if (!RHS->getType()->isIntegerTy(1))
465     RHS = Builder.CreateIsNotNull(RHS);
466 
467   switch (OpType) {
468   default:
469     llvm_unreachable("Unsupported boolean expression");
470   case isl_ast_op_and:
471     Res = Builder.CreateAnd(LHS, RHS);
472     break;
473   case isl_ast_op_or:
474     Res = Builder.CreateOr(LHS, RHS);
475     break;
476   }
477 
478   isl_ast_expr_free(Expr);
479   return Res;
480 }
481 
482 Value *
483 IslExprBuilder::createOpBooleanConditional(__isl_take isl_ast_expr *Expr) {
484   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
485          "Expected an isl_ast_expr_op expression");
486 
487   Value *LHS, *RHS;
488   isl_ast_op_type OpType;
489 
490   Function *F = Builder.GetInsertBlock()->getParent();
491   LLVMContext &Context = F->getContext();
492 
493   OpType = isl_ast_expr_get_op_type(Expr);
494 
495   assert((OpType == isl_ast_op_and_then || OpType == isl_ast_op_or_else) &&
496          "Unsupported isl_ast_op_type");
497 
498   auto InsertBB = Builder.GetInsertBlock();
499   auto InsertPoint = Builder.GetInsertPoint();
500   auto NextBB = SplitBlock(InsertBB, &*InsertPoint, &DT, &LI);
501   BasicBlock *CondBB = BasicBlock::Create(Context, "polly.cond", F);
502   LI.changeLoopFor(CondBB, LI.getLoopFor(InsertBB));
503   DT.addNewBlock(CondBB, InsertBB);
504 
505   InsertBB->getTerminator()->eraseFromParent();
506   Builder.SetInsertPoint(InsertBB);
507   auto BR = Builder.CreateCondBr(Builder.getTrue(), NextBB, CondBB);
508 
509   Builder.SetInsertPoint(CondBB);
510   Builder.CreateBr(NextBB);
511 
512   Builder.SetInsertPoint(InsertBB->getTerminator());
513 
514   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
515   if (!LHS->getType()->isIntegerTy(1))
516     LHS = Builder.CreateIsNotNull(LHS);
517   auto LeftBB = Builder.GetInsertBlock();
518 
519   if (OpType == isl_ast_op_and || OpType == isl_ast_op_and_then)
520     BR->setCondition(Builder.CreateNeg(LHS));
521   else
522     BR->setCondition(LHS);
523 
524   Builder.SetInsertPoint(CondBB->getTerminator());
525   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
526   if (!RHS->getType()->isIntegerTy(1))
527     RHS = Builder.CreateIsNotNull(RHS);
528   auto RightBB = Builder.GetInsertBlock();
529 
530   Builder.SetInsertPoint(NextBB->getTerminator());
531   auto PHI = Builder.CreatePHI(Builder.getInt1Ty(), 2);
532   PHI->addIncoming(OpType == isl_ast_op_and_then ? Builder.getFalse()
533                                                  : Builder.getTrue(),
534                    LeftBB);
535   PHI->addIncoming(RHS, RightBB);
536 
537   isl_ast_expr_free(Expr);
538   return PHI;
539 }
540 
541 Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) {
542   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
543          "Expression not of type isl_ast_expr_op");
544   switch (isl_ast_expr_get_op_type(Expr)) {
545   case isl_ast_op_error:
546   case isl_ast_op_cond:
547   case isl_ast_op_call:
548   case isl_ast_op_member:
549     llvm_unreachable("Unsupported isl ast expression");
550   case isl_ast_op_access:
551     return createOpAccess(Expr);
552   case isl_ast_op_max:
553   case isl_ast_op_min:
554     return createOpNAry(Expr);
555   case isl_ast_op_add:
556   case isl_ast_op_sub:
557   case isl_ast_op_mul:
558   case isl_ast_op_div:
559   case isl_ast_op_fdiv_q: // Round towards -infty
560   case isl_ast_op_pdiv_q: // Dividend is non-negative
561   case isl_ast_op_pdiv_r: // Dividend is non-negative
562   case isl_ast_op_zdiv_r: // Result only compared against zero
563     return createOpBin(Expr);
564   case isl_ast_op_minus:
565     return createOpUnary(Expr);
566   case isl_ast_op_select:
567     return createOpSelect(Expr);
568   case isl_ast_op_and:
569   case isl_ast_op_or:
570     return createOpBoolean(Expr);
571   case isl_ast_op_and_then:
572   case isl_ast_op_or_else:
573     return createOpBooleanConditional(Expr);
574   case isl_ast_op_eq:
575   case isl_ast_op_le:
576   case isl_ast_op_lt:
577   case isl_ast_op_ge:
578   case isl_ast_op_gt:
579     return createOpICmp(Expr);
580   case isl_ast_op_address_of:
581     return createOpAddressOf(Expr);
582   }
583 
584   llvm_unreachable("Unsupported isl_ast_expr_op kind.");
585 }
586 
587 Value *IslExprBuilder::createOpAddressOf(__isl_take isl_ast_expr *Expr) {
588   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
589          "Expected an isl_ast_expr_op expression.");
590   assert(isl_ast_expr_get_op_n_arg(Expr) == 1 && "Address of should be unary.");
591 
592   isl_ast_expr *Op = isl_ast_expr_get_op_arg(Expr, 0);
593   assert(isl_ast_expr_get_type(Op) == isl_ast_expr_op &&
594          "Expected address of operator to be an isl_ast_expr_op expression.");
595   assert(isl_ast_expr_get_op_type(Op) == isl_ast_op_access &&
596          "Expected address of operator to be an access expression.");
597 
598   Value *V = createAccessAddress(Op);
599 
600   isl_ast_expr_free(Expr);
601 
602   return V;
603 }
604 
605 Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) {
606   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_id &&
607          "Expression not of type isl_ast_expr_ident");
608 
609   isl_id *Id;
610   Value *V;
611 
612   Id = isl_ast_expr_get_id(Expr);
613 
614   assert(IDToValue.count(Id) && "Identifier not found");
615 
616   V = IDToValue[Id];
617   if (!V)
618     V = UndefValue::get(getType(Expr));
619 
620   if (V->getType()->isPointerTy())
621     V = Builder.CreatePtrToInt(V, Builder.getIntNTy(DL.getPointerSizeInBits()));
622 
623   assert(V && "Unknown parameter id found");
624 
625   isl_id_free(Id);
626   isl_ast_expr_free(Expr);
627 
628   return V;
629 }
630 
631 IntegerType *IslExprBuilder::getType(__isl_keep isl_ast_expr *Expr) {
632   // XXX: We assume i64 is large enough. This is often true, but in general
633   //      incorrect. Also, on 32bit architectures, it would be beneficial to
634   //      use a smaller type. We can and should directly derive this information
635   //      during code generation.
636   return IntegerType::get(Builder.getContext(), 64);
637 }
638 
639 Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
640   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
641          "Expression not of type isl_ast_expr_int");
642   isl_val *Val;
643   Value *V;
644   APInt APValue;
645   IntegerType *T;
646 
647   Val = isl_ast_expr_get_val(Expr);
648   APValue = APIntFromVal(Val);
649 
650   auto BitWidth = APValue.getBitWidth();
651   if (BitWidth <= 64)
652     T = getType(Expr);
653   else
654     T = Builder.getIntNTy(BitWidth);
655 
656   APValue = APValue.sextOrSelf(T->getBitWidth());
657   V = ConstantInt::get(T, APValue);
658 
659   isl_ast_expr_free(Expr);
660   return V;
661 }
662 
663 Value *IslExprBuilder::create(__isl_take isl_ast_expr *Expr) {
664   switch (isl_ast_expr_get_type(Expr)) {
665   case isl_ast_expr_error:
666     llvm_unreachable("Code generation error");
667   case isl_ast_expr_op:
668     return createOp(Expr);
669   case isl_ast_expr_id:
670     return createId(Expr);
671   case isl_ast_expr_int:
672     return createInt(Expr);
673   }
674 
675   llvm_unreachable("Unexpected enum value");
676 }
677