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