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 
14 #include "polly/ScopInfo.h"
15 #include "polly/Support/GICHelper.h"
16 
17 #include "llvm/Analysis/ScalarEvolutionExpander.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
20 
21 using namespace llvm;
22 using namespace polly;
23 
24 Type *IslExprBuilder::getWidestType(Type *T1, Type *T2) {
25   assert(isa<IntegerType>(T1) && isa<IntegerType>(T2));
26 
27   if (T1->getPrimitiveSizeInBits() < T2->getPrimitiveSizeInBits())
28     return T2;
29   else
30     return T1;
31 }
32 
33 Value *IslExprBuilder::createOpUnary(__isl_take isl_ast_expr *Expr) {
34   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_minus &&
35          "Unsupported unary operation");
36 
37   Value *V;
38   Type *MaxType = getType(Expr);
39   assert(MaxType->isIntegerTy() &&
40          "Unary expressions can only be created for integer types");
41 
42   V = create(isl_ast_expr_get_op_arg(Expr, 0));
43   MaxType = getWidestType(MaxType, V->getType());
44 
45   if (MaxType != V->getType())
46     V = Builder.CreateSExt(V, MaxType);
47 
48   isl_ast_expr_free(Expr);
49   return Builder.CreateNSWNeg(V);
50 }
51 
52 Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
53   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
54          "isl ast expression not of type isl_ast_op");
55   assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
56          "We need at least two operands in an n-ary operation");
57 
58   Value *V;
59 
60   V = create(isl_ast_expr_get_op_arg(Expr, 0));
61 
62   for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
63     Value *OpV;
64     OpV = create(isl_ast_expr_get_op_arg(Expr, i));
65 
66     Type *Ty = getWidestType(V->getType(), OpV->getType());
67 
68     if (Ty != OpV->getType())
69       OpV = Builder.CreateSExt(OpV, Ty);
70 
71     if (Ty != V->getType())
72       V = Builder.CreateSExt(V, Ty);
73 
74     switch (isl_ast_expr_get_op_type(Expr)) {
75     default:
76       llvm_unreachable("This is no n-ary isl ast expression");
77 
78     case isl_ast_op_max: {
79       Value *Cmp = Builder.CreateICmpSGT(V, OpV);
80       V = Builder.CreateSelect(Cmp, V, OpV);
81       continue;
82     }
83     case isl_ast_op_min: {
84       Value *Cmp = Builder.CreateICmpSLT(V, OpV);
85       V = Builder.CreateSelect(Cmp, V, OpV);
86       continue;
87     }
88     }
89   }
90 
91   // TODO: We can truncate the result, if it fits into a smaller type. This can
92   // help in cases where we have larger operands (e.g. i67) but the result is
93   // known to fit into i64. Without the truncation, the larger i67 type may
94   // force all subsequent operations to be performed on a non-native type.
95   isl_ast_expr_free(Expr);
96   return V;
97 }
98 
99 Value *IslExprBuilder::createAccessAddress(isl_ast_expr *Expr) {
100   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
101          "isl ast expression not of type isl_ast_op");
102   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_access &&
103          "not an access isl ast expression");
104   assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
105          "We need at least two operands to create a member access.");
106 
107   Value *Base, *IndexOp, *Access;
108   isl_ast_expr *BaseExpr;
109   isl_id *BaseId;
110 
111   BaseExpr = isl_ast_expr_get_op_arg(Expr, 0);
112   BaseId = isl_ast_expr_get_id(BaseExpr);
113   isl_ast_expr_free(BaseExpr);
114 
115   const ScopArrayInfo *SAI = ScopArrayInfo::getFromId(BaseId);
116   Base = SAI->getBasePtr();
117   assert(Base->getType()->isPointerTy() && "Access base should be a pointer");
118   StringRef BaseName = Base->getName();
119 
120   if (Base->getType() != SAI->getType())
121     Base = Builder.CreateBitCast(Base, SAI->getType(),
122                                  "polly.access.cast." + BaseName);
123 
124   IndexOp = nullptr;
125   for (unsigned u = 1, e = isl_ast_expr_get_op_n_arg(Expr); u < e; u++) {
126     Value *NextIndex = create(isl_ast_expr_get_op_arg(Expr, u));
127     assert(NextIndex->getType()->isIntegerTy() &&
128            "Access index should be an integer");
129 
130     if (!IndexOp) {
131       IndexOp = NextIndex;
132     } else {
133       Type *Ty = getWidestType(NextIndex->getType(), IndexOp->getType());
134 
135       if (Ty != NextIndex->getType())
136         NextIndex = Builder.CreateIntCast(NextIndex, Ty, true);
137       if (Ty != IndexOp->getType())
138         IndexOp = Builder.CreateIntCast(IndexOp, Ty, true);
139 
140       IndexOp =
141           Builder.CreateAdd(IndexOp, NextIndex, "polly.access.add." + BaseName);
142     }
143 
144     // For every but the last dimension multiply the size, for the last
145     // dimension we can exit the loop.
146     if (u + 1 >= e)
147       break;
148 
149     const SCEV *DimSCEV = SAI->getDimensionSize(u - 1);
150     Value *DimSize = Expander.expandCodeFor(DimSCEV, DimSCEV->getType(),
151                                             Builder.GetInsertPoint());
152 
153     Type *Ty = getWidestType(DimSize->getType(), IndexOp->getType());
154 
155     if (Ty != IndexOp->getType())
156       IndexOp = Builder.CreateSExtOrTrunc(IndexOp, Ty,
157                                           "polly.access.sext." + BaseName);
158     if (Ty != DimSize->getType())
159       DimSize = Builder.CreateSExtOrTrunc(DimSize, Ty,
160                                           "polly.access.sext." + BaseName);
161     IndexOp =
162         Builder.CreateMul(IndexOp, DimSize, "polly.access.mul." + BaseName);
163   }
164 
165   Access = Builder.CreateGEP(Base, IndexOp, "polly.access." + BaseName);
166 
167   isl_ast_expr_free(Expr);
168   return Access;
169 }
170 
171 Value *IslExprBuilder::createOpAccess(isl_ast_expr *Expr) {
172   Value *Addr = createAccessAddress(Expr);
173   assert(Addr && "Could not create op access address");
174   return Builder.CreateLoad(Addr, Addr->getName() + ".load");
175 }
176 
177 Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) {
178   Value *LHS, *RHS, *Res;
179   Type *MaxType;
180   isl_ast_expr *LOp, *ROp;
181   isl_ast_op_type OpType;
182 
183   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
184          "isl ast expression not of type isl_ast_op");
185   assert(isl_ast_expr_get_op_n_arg(Expr) == 2 &&
186          "not a binary isl ast expression");
187 
188   OpType = isl_ast_expr_get_op_type(Expr);
189 
190   LOp = isl_ast_expr_get_op_arg(Expr, 0);
191   ROp = isl_ast_expr_get_op_arg(Expr, 1);
192 
193   // Catch the special case ((-<pointer>) + <pointer>) which is for
194   // isl the same as (<pointer> - <pointer>). We have to treat it here because
195   // there is no valid semantics for the (-<pointer>) expression, hence in
196   // createOpUnary such an expression will trigger a crash.
197   // FIXME: The same problem can now be triggered by a subexpression of the LHS,
198   //        however it is much less likely.
199   if (OpType == isl_ast_op_add &&
200       isl_ast_expr_get_type(LOp) == isl_ast_expr_op &&
201       isl_ast_expr_get_op_type(LOp) == isl_ast_op_minus) {
202     // Change the binary addition to a substraction.
203     OpType = isl_ast_op_sub;
204 
205     // Extract the unary operand of the LHS.
206     auto *LOpOp = isl_ast_expr_get_op_arg(LOp, 0);
207     isl_ast_expr_free(LOp);
208 
209     // Swap the unary operand of the LHS and the RHS.
210     LOp = ROp;
211     ROp = LOpOp;
212   }
213 
214   LHS = create(LOp);
215   RHS = create(ROp);
216 
217   Type *LHSType = LHS->getType();
218   Type *RHSType = RHS->getType();
219 
220   // Handle <pointer> - <pointer>
221   if (LHSType->isPointerTy() && RHSType->isPointerTy()) {
222     isl_ast_expr_free(Expr);
223     assert(OpType == isl_ast_op_sub && "Substraction is the only valid binary "
224                                        "pointer <-> pointer operation.");
225 
226     return Builder.CreatePtrDiff(LHS, RHS);
227   }
228 
229   // Handle <pointer> +/- <integer> and <integer> +/- <pointer>
230   if (LHSType->isPointerTy() || RHSType->isPointerTy()) {
231     isl_ast_expr_free(Expr);
232 
233     assert((LHSType->isIntegerTy() || RHSType->isIntegerTy()) &&
234            "Arithmetic operations might only performed on one but not two "
235            "pointer types.");
236 
237     if (LHSType->isIntegerTy())
238       std::swap(LHS, RHS);
239 
240     switch (OpType) {
241     default:
242       llvm_unreachable(
243           "Only additive binary operations are allowed on pointer types.");
244     case isl_ast_op_sub:
245       RHS = Builder.CreateNeg(RHS);
246     // Fall through
247     case isl_ast_op_add:
248       return Builder.CreateGEP(LHS, RHS);
249     }
250   }
251 
252   MaxType = getWidestType(LHSType, RHSType);
253 
254   // Take the result into account when calculating the widest type.
255   //
256   // For operations such as '+' the result may require a type larger than
257   // the type of the individual operands. For other operations such as '/', the
258   // result type cannot be larger than the type of the individual operand. isl
259   // does not calculate correct types for these operations and we consequently
260   // exclude those operations here.
261   switch (OpType) {
262   case isl_ast_op_pdiv_q:
263   case isl_ast_op_pdiv_r:
264   case isl_ast_op_div:
265   case isl_ast_op_fdiv_q:
266   case isl_ast_op_zdiv_r:
267     // Do nothing
268     break;
269   case isl_ast_op_add:
270   case isl_ast_op_sub:
271   case isl_ast_op_mul:
272     MaxType = getWidestType(MaxType, getType(Expr));
273     break;
274   default:
275     llvm_unreachable("This is no binary isl ast expression");
276   }
277 
278   if (MaxType != RHS->getType())
279     RHS = Builder.CreateSExt(RHS, MaxType);
280 
281   if (MaxType != LHS->getType())
282     LHS = Builder.CreateSExt(LHS, MaxType);
283 
284   switch (OpType) {
285   default:
286     llvm_unreachable("This is no binary isl ast expression");
287   case isl_ast_op_add:
288     Res = Builder.CreateNSWAdd(LHS, RHS);
289     break;
290   case isl_ast_op_sub:
291     Res = Builder.CreateNSWSub(LHS, RHS);
292     break;
293   case isl_ast_op_mul:
294     Res = Builder.CreateNSWMul(LHS, RHS);
295     break;
296   case isl_ast_op_div:
297   case isl_ast_op_pdiv_q: // Dividend is non-negative
298     Res = Builder.CreateSDiv(LHS, RHS);
299     break;
300   case isl_ast_op_fdiv_q: { // Round towards -infty
301     // TODO: Review code and check that this calculation does not yield
302     //       incorrect overflow in some bordercases.
303     //
304     // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
305     Value *One = ConstantInt::get(MaxType, 1);
306     Value *Zero = ConstantInt::get(MaxType, 0);
307     Value *Sum1 = Builder.CreateSub(LHS, RHS);
308     Value *Sum2 = Builder.CreateAdd(Sum1, One);
309     Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
310     Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
311     Res = Builder.CreateSDiv(Dividend, RHS);
312     break;
313   }
314   case isl_ast_op_pdiv_r: // Dividend is non-negative
315   case isl_ast_op_zdiv_r: // Result only compared against zero
316     Res = Builder.CreateSRem(LHS, RHS);
317     break;
318   }
319 
320   // TODO: We can truncate the result, if it fits into a smaller type. This can
321   // help in cases where we have larger operands (e.g. i67) but the result is
322   // known to fit into i64. Without the truncation, the larger i67 type may
323   // force all subsequent operations to be performed on a non-native type.
324   isl_ast_expr_free(Expr);
325   return Res;
326 }
327 
328 Value *IslExprBuilder::createOpSelect(__isl_take isl_ast_expr *Expr) {
329   assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_select &&
330          "Unsupported unary isl ast expression");
331   Value *LHS, *RHS, *Cond;
332   Type *MaxType = getType(Expr);
333 
334   Cond = create(isl_ast_expr_get_op_arg(Expr, 0));
335   if (!Cond->getType()->isIntegerTy(1))
336     Cond = Builder.CreateIsNotNull(Cond);
337 
338   LHS = create(isl_ast_expr_get_op_arg(Expr, 1));
339   RHS = create(isl_ast_expr_get_op_arg(Expr, 2));
340 
341   MaxType = getWidestType(MaxType, LHS->getType());
342   MaxType = getWidestType(MaxType, RHS->getType());
343 
344   if (MaxType != RHS->getType())
345     RHS = Builder.CreateSExt(RHS, MaxType);
346 
347   if (MaxType != LHS->getType())
348     LHS = Builder.CreateSExt(LHS, MaxType);
349 
350   // TODO: Do we want to truncate the result?
351   isl_ast_expr_free(Expr);
352   return Builder.CreateSelect(Cond, LHS, RHS);
353 }
354 
355 Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) {
356   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
357          "Expected an isl_ast_expr_op expression");
358 
359   Value *LHS, *RHS, *Res;
360 
361   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
362   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
363 
364   bool IsPtrType =
365       LHS->getType()->isPointerTy() || RHS->getType()->isPointerTy();
366 
367   if (LHS->getType() != RHS->getType()) {
368     if (IsPtrType) {
369       Type *I8PtrTy = Builder.getInt8PtrTy();
370       if (!LHS->getType()->isPointerTy())
371         LHS = Builder.CreateIntToPtr(LHS, I8PtrTy);
372       if (!RHS->getType()->isPointerTy())
373         RHS = Builder.CreateIntToPtr(RHS, I8PtrTy);
374       if (LHS->getType() != I8PtrTy)
375         LHS = Builder.CreateBitCast(LHS, I8PtrTy);
376       if (RHS->getType() != I8PtrTy)
377         RHS = Builder.CreateBitCast(RHS, I8PtrTy);
378     } else {
379       Type *MaxType = LHS->getType();
380       MaxType = getWidestType(MaxType, RHS->getType());
381 
382       if (MaxType != RHS->getType())
383         RHS = Builder.CreateSExt(RHS, MaxType);
384 
385       if (MaxType != LHS->getType())
386         LHS = Builder.CreateSExt(LHS, MaxType);
387     }
388   }
389 
390   isl_ast_op_type OpType = isl_ast_expr_get_op_type(Expr);
391   assert(OpType >= isl_ast_op_eq && OpType <= isl_ast_op_gt &&
392          "Unsupported ICmp isl ast expression");
393   assert(isl_ast_op_eq + 4 == isl_ast_op_gt &&
394          "Isl ast op type interface changed");
395 
396   CmpInst::Predicate Predicates[5][2] = {
397       {CmpInst::ICMP_EQ, CmpInst::ICMP_EQ},
398       {CmpInst::ICMP_SLE, CmpInst::ICMP_ULE},
399       {CmpInst::ICMP_SLT, CmpInst::ICMP_ULT},
400       {CmpInst::ICMP_SGE, CmpInst::ICMP_UGE},
401       {CmpInst::ICMP_SGT, CmpInst::ICMP_UGT},
402   };
403 
404   Res = Builder.CreateICmp(Predicates[OpType - isl_ast_op_eq][IsPtrType], LHS,
405                            RHS);
406 
407   isl_ast_expr_free(Expr);
408   return Res;
409 }
410 
411 Value *IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr *Expr) {
412   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
413          "Expected an isl_ast_expr_op expression");
414 
415   Value *LHS, *RHS, *Res;
416   isl_ast_op_type OpType;
417 
418   OpType = isl_ast_expr_get_op_type(Expr);
419 
420   assert((OpType == isl_ast_op_and || OpType == isl_ast_op_or) &&
421          "Unsupported isl_ast_op_type");
422 
423   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
424   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
425 
426   // Even though the isl pretty printer prints the expressions as 'exp && exp'
427   // or 'exp || exp', we actually code generate the bitwise expressions
428   // 'exp & exp' or 'exp | exp'. This forces the evaluation of both branches,
429   // but it is, due to the use of i1 types, otherwise equivalent. The reason
430   // to go for bitwise operations is, that we assume the reduced control flow
431   // will outweight the overhead introduced by evaluating unneeded expressions.
432   // The isl code generation currently does not take advantage of the fact that
433   // the expression after an '||' or '&&' is in some cases not evaluated.
434   // Evaluating it anyways does not cause any undefined behaviour.
435   //
436   // TODO: Document in isl itself, that the unconditionally evaluating the
437   // second part of '||' or '&&' expressions is safe.
438   if (!LHS->getType()->isIntegerTy(1))
439     LHS = Builder.CreateIsNotNull(LHS);
440   if (!RHS->getType()->isIntegerTy(1))
441     RHS = Builder.CreateIsNotNull(RHS);
442 
443   switch (OpType) {
444   default:
445     llvm_unreachable("Unsupported boolean expression");
446   case isl_ast_op_and:
447     Res = Builder.CreateAnd(LHS, RHS);
448     break;
449   case isl_ast_op_or:
450     Res = Builder.CreateOr(LHS, RHS);
451     break;
452   }
453 
454   isl_ast_expr_free(Expr);
455   return Res;
456 }
457 
458 Value *
459 IslExprBuilder::createOpBooleanConditional(__isl_take isl_ast_expr *Expr) {
460   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
461          "Expected an isl_ast_expr_op expression");
462 
463   Value *LHS, *RHS;
464   isl_ast_op_type OpType;
465 
466   Function *F = Builder.GetInsertBlock()->getParent();
467   LLVMContext &Context = F->getContext();
468 
469   OpType = isl_ast_expr_get_op_type(Expr);
470 
471   assert((OpType == isl_ast_op_and_then || OpType == isl_ast_op_or_else) &&
472          "Unsupported isl_ast_op_type");
473 
474   auto InsertBB = Builder.GetInsertBlock();
475   auto InsertPoint = Builder.GetInsertPoint();
476   auto NextBB = SplitBlock(InsertBB, InsertPoint, &DT, &LI);
477   BasicBlock *CondBB = BasicBlock::Create(Context, "polly.cond", F);
478   LI.changeLoopFor(CondBB, LI.getLoopFor(InsertBB));
479   DT.addNewBlock(CondBB, InsertBB);
480 
481   InsertBB->getTerminator()->eraseFromParent();
482   Builder.SetInsertPoint(InsertBB);
483   auto BR = Builder.CreateCondBr(Builder.getTrue(), NextBB, CondBB);
484 
485   Builder.SetInsertPoint(CondBB);
486   Builder.CreateBr(NextBB);
487 
488   Builder.SetInsertPoint(InsertBB->getTerminator());
489 
490   LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
491   if (!LHS->getType()->isIntegerTy(1))
492     LHS = Builder.CreateIsNotNull(LHS);
493   auto LeftBB = Builder.GetInsertBlock();
494 
495   if (OpType == isl_ast_op_and || OpType == isl_ast_op_and_then)
496     BR->setCondition(Builder.CreateNeg(LHS));
497   else
498     BR->setCondition(LHS);
499 
500   Builder.SetInsertPoint(CondBB->getTerminator());
501   RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
502   if (!RHS->getType()->isIntegerTy(1))
503     RHS = Builder.CreateIsNotNull(RHS);
504   auto RightBB = Builder.GetInsertBlock();
505 
506   Builder.SetInsertPoint(NextBB->getTerminator());
507   auto PHI = Builder.CreatePHI(Builder.getInt1Ty(), 2);
508   PHI->addIncoming(OpType == isl_ast_op_and_then ? Builder.getFalse()
509                                                  : Builder.getTrue(),
510                    LeftBB);
511   PHI->addIncoming(RHS, RightBB);
512 
513   isl_ast_expr_free(Expr);
514   return PHI;
515 }
516 
517 Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) {
518   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
519          "Expression not of type isl_ast_expr_op");
520   switch (isl_ast_expr_get_op_type(Expr)) {
521   case isl_ast_op_error:
522   case isl_ast_op_cond:
523   case isl_ast_op_call:
524   case isl_ast_op_member:
525     llvm_unreachable("Unsupported isl ast expression");
526   case isl_ast_op_access:
527     return createOpAccess(Expr);
528   case isl_ast_op_max:
529   case isl_ast_op_min:
530     return createOpNAry(Expr);
531   case isl_ast_op_add:
532   case isl_ast_op_sub:
533   case isl_ast_op_mul:
534   case isl_ast_op_div:
535   case isl_ast_op_fdiv_q: // Round towards -infty
536   case isl_ast_op_pdiv_q: // Dividend is non-negative
537   case isl_ast_op_pdiv_r: // Dividend is non-negative
538   case isl_ast_op_zdiv_r: // Result only compared against zero
539     return createOpBin(Expr);
540   case isl_ast_op_minus:
541     return createOpUnary(Expr);
542   case isl_ast_op_select:
543     return createOpSelect(Expr);
544   case isl_ast_op_and:
545   case isl_ast_op_or:
546     return createOpBoolean(Expr);
547   case isl_ast_op_and_then:
548   case isl_ast_op_or_else:
549     return createOpBooleanConditional(Expr);
550   case isl_ast_op_eq:
551   case isl_ast_op_le:
552   case isl_ast_op_lt:
553   case isl_ast_op_ge:
554   case isl_ast_op_gt:
555     return createOpICmp(Expr);
556   case isl_ast_op_address_of:
557     return createOpAddressOf(Expr);
558   }
559 
560   llvm_unreachable("Unsupported isl_ast_expr_op kind.");
561 }
562 
563 Value *IslExprBuilder::createOpAddressOf(__isl_take isl_ast_expr *Expr) {
564   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
565          "Expected an isl_ast_expr_op expression.");
566   assert(isl_ast_expr_get_op_n_arg(Expr) == 1 && "Address of should be unary.");
567 
568   isl_ast_expr *Op = isl_ast_expr_get_op_arg(Expr, 0);
569   assert(isl_ast_expr_get_type(Op) == isl_ast_expr_op &&
570          "Expected address of operator to be an isl_ast_expr_op expression.");
571   assert(isl_ast_expr_get_op_type(Op) == isl_ast_op_access &&
572          "Expected address of operator to be an access expression.");
573 
574   Value *V = createAccessAddress(Op);
575 
576   isl_ast_expr_free(Expr);
577 
578   return V;
579 }
580 
581 Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) {
582   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_id &&
583          "Expression not of type isl_ast_expr_ident");
584 
585   isl_id *Id;
586   Value *V;
587 
588   Id = isl_ast_expr_get_id(Expr);
589 
590   assert(IDToValue.count(Id) && "Identifier not found");
591 
592   V = IDToValue[Id];
593 
594   assert(V && "Unknown parameter id found");
595 
596   isl_id_free(Id);
597   isl_ast_expr_free(Expr);
598 
599   return V;
600 }
601 
602 IntegerType *IslExprBuilder::getType(__isl_keep isl_ast_expr *Expr) {
603   // XXX: We assume i64 is large enough. This is often true, but in general
604   //      incorrect. Also, on 32bit architectures, it would be beneficial to
605   //      use a smaller type. We can and should directly derive this information
606   //      during code generation.
607   return IntegerType::get(Builder.getContext(), 64);
608 }
609 
610 Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
611   assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
612          "Expression not of type isl_ast_expr_int");
613   isl_val *Val;
614   Value *V;
615   APInt APValue;
616   IntegerType *T;
617 
618   Val = isl_ast_expr_get_val(Expr);
619   APValue = APIntFromVal(Val);
620   T = getType(Expr);
621   APValue = APValue.sextOrSelf(T->getBitWidth());
622   V = ConstantInt::get(T, APValue);
623 
624   isl_ast_expr_free(Expr);
625   return V;
626 }
627 
628 Value *IslExprBuilder::create(__isl_take isl_ast_expr *Expr) {
629   switch (isl_ast_expr_get_type(Expr)) {
630   case isl_ast_expr_error:
631     llvm_unreachable("Code generation error");
632   case isl_ast_expr_op:
633     return createOp(Expr);
634   case isl_ast_expr_id:
635     return createId(Expr);
636   case isl_ast_expr_int:
637     return createInt(Expr);
638   }
639 
640   llvm_unreachable("Unexpected enum value");
641 }
642