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