1 //===- IslNodeBuilder.cpp - Translate an isl AST into a LLVM-IR AST -------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the IslNodeBuilder, a class to translate an isl AST into 10 // a LLVM-IR AST. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "polly/CodeGen/IslNodeBuilder.h" 15 #include "polly/CodeGen/BlockGenerators.h" 16 #include "polly/CodeGen/CodeGeneration.h" 17 #include "polly/CodeGen/IslAst.h" 18 #include "polly/CodeGen/IslExprBuilder.h" 19 #include "polly/CodeGen/LoopGeneratorsGOMP.h" 20 #include "polly/CodeGen/LoopGeneratorsKMP.h" 21 #include "polly/CodeGen/RuntimeDebugBuilder.h" 22 #include "polly/Options.h" 23 #include "polly/ScopInfo.h" 24 #include "polly/Support/ISLTools.h" 25 #include "polly/Support/SCEVValidator.h" 26 #include "polly/Support/ScopHelper.h" 27 #include "polly/Support/VirtualInstruction.h" 28 #include "llvm/ADT/APInt.h" 29 #include "llvm/ADT/PostOrderIterator.h" 30 #include "llvm/ADT/SetVector.h" 31 #include "llvm/ADT/SmallPtrSet.h" 32 #include "llvm/ADT/Statistic.h" 33 #include "llvm/Analysis/LoopInfo.h" 34 #include "llvm/Analysis/RegionInfo.h" 35 #include "llvm/Analysis/ScalarEvolution.h" 36 #include "llvm/Analysis/ScalarEvolutionExpressions.h" 37 #include "llvm/IR/BasicBlock.h" 38 #include "llvm/IR/Constant.h" 39 #include "llvm/IR/Constants.h" 40 #include "llvm/IR/DataLayout.h" 41 #include "llvm/IR/DerivedTypes.h" 42 #include "llvm/IR/Dominators.h" 43 #include "llvm/IR/Function.h" 44 #include "llvm/IR/InstrTypes.h" 45 #include "llvm/IR/Instruction.h" 46 #include "llvm/IR/Instructions.h" 47 #include "llvm/IR/Type.h" 48 #include "llvm/IR/Value.h" 49 #include "llvm/Support/Casting.h" 50 #include "llvm/Support/CommandLine.h" 51 #include "llvm/Support/ErrorHandling.h" 52 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 53 #include "isl/aff.h" 54 #include "isl/aff_type.h" 55 #include "isl/ast.h" 56 #include "isl/ast_build.h" 57 #include "isl/isl-noexceptions.h" 58 #include "isl/map.h" 59 #include "isl/set.h" 60 #include "isl/union_map.h" 61 #include "isl/union_set.h" 62 #include "isl/val.h" 63 #include <algorithm> 64 #include <cassert> 65 #include <cstdint> 66 #include <cstring> 67 #include <string> 68 #include <utility> 69 #include <vector> 70 71 using namespace llvm; 72 using namespace polly; 73 74 #define DEBUG_TYPE "polly-codegen" 75 76 STATISTIC(VersionedScops, "Number of SCoPs that required versioning."); 77 78 STATISTIC(SequentialLoops, "Number of generated sequential for-loops"); 79 STATISTIC(ParallelLoops, "Number of generated parallel for-loops"); 80 STATISTIC(VectorLoops, "Number of generated vector for-loops"); 81 STATISTIC(IfConditions, "Number of generated if-conditions"); 82 83 /// OpenMP backend options 84 enum class OpenMPBackend { GNU, LLVM }; 85 86 static cl::opt<bool> PollyGenerateRTCPrint( 87 "polly-codegen-emit-rtc-print", 88 cl::desc("Emit code that prints the runtime check result dynamically."), 89 cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); 90 91 // If this option is set we always use the isl AST generator to regenerate 92 // memory accesses. Without this option set we regenerate expressions using the 93 // original SCEV expressions and only generate new expressions in case the 94 // access relation has been changed and consequently must be regenerated. 95 static cl::opt<bool> PollyGenerateExpressions( 96 "polly-codegen-generate-expressions", 97 cl::desc("Generate AST expressions for unmodified and modified accesses"), 98 cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); 99 100 static cl::opt<int> PollyTargetFirstLevelCacheLineSize( 101 "polly-target-first-level-cache-line-size", 102 cl::desc("The size of the first level cache line size specified in bytes."), 103 cl::Hidden, cl::init(64), cl::ZeroOrMore, cl::cat(PollyCategory)); 104 105 static cl::opt<OpenMPBackend> PollyOmpBackend( 106 "polly-omp-backend", cl::desc("Choose the OpenMP library to use:"), 107 cl::values(clEnumValN(OpenMPBackend::GNU, "GNU", "GNU OpenMP"), 108 clEnumValN(OpenMPBackend::LLVM, "LLVM", "LLVM OpenMP")), 109 cl::Hidden, cl::init(OpenMPBackend::GNU), cl::cat(PollyCategory)); 110 111 isl::ast_expr IslNodeBuilder::getUpperBound(isl::ast_node_for For, 112 ICmpInst::Predicate &Predicate) { 113 isl::ast_expr Cond = For.cond(); 114 isl::ast_expr Iterator = For.iterator(); 115 assert(isl_ast_expr_get_type(Cond.get()) == isl_ast_expr_op && 116 "conditional expression is not an atomic upper bound"); 117 118 isl_ast_op_type OpType = isl_ast_expr_get_op_type(Cond.get()); 119 120 switch (OpType) { 121 case isl_ast_op_le: 122 Predicate = ICmpInst::ICMP_SLE; 123 break; 124 case isl_ast_op_lt: 125 Predicate = ICmpInst::ICMP_SLT; 126 break; 127 default: 128 llvm_unreachable("Unexpected comparison type in loop condition"); 129 } 130 131 isl::ast_expr Arg0 = Cond.get_op_arg(0); 132 133 assert(isl_ast_expr_get_type(Arg0.get()) == isl_ast_expr_id && 134 "conditional expression is not an atomic upper bound"); 135 136 isl::id UBID = Arg0.get_id(); 137 138 assert(isl_ast_expr_get_type(Iterator.get()) == isl_ast_expr_id && 139 "Could not get the iterator"); 140 141 isl::id IteratorID = Iterator.get_id(); 142 143 assert(UBID.get() == IteratorID.get() && 144 "conditional expression is not an atomic upper bound"); 145 146 return Cond.get_op_arg(1); 147 } 148 149 /// Return true if a return value of Predicate is true for the value represented 150 /// by passed isl_ast_expr_int. 151 static bool checkIslAstExprInt(__isl_take isl_ast_expr *Expr, 152 isl_bool (*Predicate)(__isl_keep isl_val *)) { 153 if (isl_ast_expr_get_type(Expr) != isl_ast_expr_int) { 154 isl_ast_expr_free(Expr); 155 return false; 156 } 157 auto ExprVal = isl_ast_expr_get_val(Expr); 158 isl_ast_expr_free(Expr); 159 if (Predicate(ExprVal) != isl_bool_true) { 160 isl_val_free(ExprVal); 161 return false; 162 } 163 isl_val_free(ExprVal); 164 return true; 165 } 166 167 int IslNodeBuilder::getNumberOfIterations(isl::ast_node_for For) { 168 assert(isl_ast_node_get_type(For.get()) == isl_ast_node_for); 169 isl::ast_node Body = For.body(); 170 171 // First, check if we can actually handle this code. 172 switch (isl_ast_node_get_type(Body.get())) { 173 case isl_ast_node_user: 174 break; 175 case isl_ast_node_block: { 176 isl::ast_node_block BodyBlock = Body.as<isl::ast_node_block>(); 177 isl::ast_node_list List = BodyBlock.children(); 178 for (isl::ast_node Node : List) { 179 isl_ast_node_type NodeType = isl_ast_node_get_type(Node.get()); 180 if (NodeType != isl_ast_node_user) 181 return -1; 182 } 183 break; 184 } 185 default: 186 return -1; 187 } 188 189 isl::ast_expr Init = For.init(); 190 if (!checkIslAstExprInt(Init.release(), isl_val_is_zero)) 191 return -1; 192 isl::ast_expr Inc = For.inc(); 193 if (!checkIslAstExprInt(Inc.release(), isl_val_is_one)) 194 return -1; 195 CmpInst::Predicate Predicate; 196 isl::ast_expr UB = getUpperBound(For, Predicate); 197 if (isl_ast_expr_get_type(UB.get()) != isl_ast_expr_int) 198 return -1; 199 isl::val UpVal = UB.get_val(); 200 int NumberIterations = UpVal.get_num_si(); 201 if (NumberIterations < 0) 202 return -1; 203 if (Predicate == CmpInst::ICMP_SLT) 204 return NumberIterations; 205 else 206 return NumberIterations + 1; 207 } 208 209 static void findReferencesByUse(Value *SrcVal, ScopStmt *UserStmt, 210 Loop *UserScope, const ValueMapT &GlobalMap, 211 SetVector<Value *> &Values, 212 SetVector<const SCEV *> &SCEVs) { 213 VirtualUse VUse = VirtualUse::create(UserStmt, UserScope, SrcVal, true); 214 switch (VUse.getKind()) { 215 case VirtualUse::Constant: 216 // When accelerator-offloading, GlobalValue is a host address whose content 217 // must still be transferred to the GPU. 218 if (isa<GlobalValue>(SrcVal)) 219 Values.insert(SrcVal); 220 break; 221 222 case VirtualUse::Synthesizable: 223 SCEVs.insert(VUse.getScevExpr()); 224 return; 225 226 case VirtualUse::Block: 227 case VirtualUse::ReadOnly: 228 case VirtualUse::Hoisted: 229 case VirtualUse::Intra: 230 case VirtualUse::Inter: 231 break; 232 } 233 234 if (Value *NewVal = GlobalMap.lookup(SrcVal)) 235 Values.insert(NewVal); 236 } 237 238 static void findReferencesInInst(Instruction *Inst, ScopStmt *UserStmt, 239 Loop *UserScope, const ValueMapT &GlobalMap, 240 SetVector<Value *> &Values, 241 SetVector<const SCEV *> &SCEVs) { 242 for (Use &U : Inst->operands()) 243 findReferencesByUse(U.get(), UserStmt, UserScope, GlobalMap, Values, SCEVs); 244 } 245 246 static void findReferencesInStmt(ScopStmt *Stmt, SetVector<Value *> &Values, 247 ValueMapT &GlobalMap, 248 SetVector<const SCEV *> &SCEVs) { 249 LoopInfo *LI = Stmt->getParent()->getLI(); 250 251 BasicBlock *BB = Stmt->getBasicBlock(); 252 Loop *Scope = LI->getLoopFor(BB); 253 for (Instruction *Inst : Stmt->getInstructions()) 254 findReferencesInInst(Inst, Stmt, Scope, GlobalMap, Values, SCEVs); 255 256 if (Stmt->isRegionStmt()) { 257 for (BasicBlock *BB : Stmt->getRegion()->blocks()) { 258 Loop *Scope = LI->getLoopFor(BB); 259 for (Instruction &Inst : *BB) 260 findReferencesInInst(&Inst, Stmt, Scope, GlobalMap, Values, SCEVs); 261 } 262 } 263 } 264 265 void polly::addReferencesFromStmt(ScopStmt *Stmt, void *UserPtr, 266 bool CreateScalarRefs) { 267 auto &References = *static_cast<struct SubtreeReferences *>(UserPtr); 268 269 findReferencesInStmt(Stmt, References.Values, References.GlobalMap, 270 References.SCEVs); 271 272 for (auto &Access : *Stmt) { 273 if (References.ParamSpace) { 274 isl::space ParamSpace = Access->getLatestAccessRelation().get_space(); 275 (*References.ParamSpace) = 276 References.ParamSpace->align_params(ParamSpace); 277 } 278 279 if (Access->isLatestArrayKind()) { 280 auto *BasePtr = Access->getLatestScopArrayInfo()->getBasePtr(); 281 if (Instruction *OpInst = dyn_cast<Instruction>(BasePtr)) 282 if (Stmt->getParent()->contains(OpInst)) 283 continue; 284 285 References.Values.insert(BasePtr); 286 continue; 287 } 288 289 if (CreateScalarRefs) 290 References.Values.insert(References.BlockGen.getOrCreateAlloca(*Access)); 291 } 292 } 293 294 /// Extract the out-of-scop values and SCEVs referenced from a set describing 295 /// a ScopStmt. 296 /// 297 /// This includes the SCEVUnknowns referenced by the SCEVs used in the 298 /// statement and the base pointers of the memory accesses. For scalar 299 /// statements we force the generation of alloca memory locations and list 300 /// these locations in the set of out-of-scop values as well. 301 /// 302 /// @param Set A set which references the ScopStmt we are interested in. 303 /// @param UserPtr A void pointer that can be casted to a SubtreeReferences 304 /// structure. 305 static void addReferencesFromStmtSet(isl::set Set, 306 struct SubtreeReferences *UserPtr) { 307 isl::id Id = Set.get_tuple_id(); 308 auto *Stmt = static_cast<ScopStmt *>(Id.get_user()); 309 addReferencesFromStmt(Stmt, UserPtr); 310 } 311 312 /// Extract the out-of-scop values and SCEVs referenced from a union set 313 /// referencing multiple ScopStmts. 314 /// 315 /// This includes the SCEVUnknowns referenced by the SCEVs used in the 316 /// statement and the base pointers of the memory accesses. For scalar 317 /// statements we force the generation of alloca memory locations and list 318 /// these locations in the set of out-of-scop values as well. 319 /// 320 /// @param USet A union set referencing the ScopStmts we are interested 321 /// in. 322 /// @param References The SubtreeReferences data structure through which 323 /// results are returned and further information is 324 /// provided. 325 static void 326 addReferencesFromStmtUnionSet(isl::union_set USet, 327 struct SubtreeReferences &References) { 328 329 for (isl::set Set : USet.get_set_list()) 330 addReferencesFromStmtSet(Set, &References); 331 } 332 333 isl::union_map 334 IslNodeBuilder::getScheduleForAstNode(const isl::ast_node &Node) { 335 return IslAstInfo::getSchedule(Node); 336 } 337 338 void IslNodeBuilder::getReferencesInSubtree(const isl::ast_node &For, 339 SetVector<Value *> &Values, 340 SetVector<const Loop *> &Loops) { 341 SetVector<const SCEV *> SCEVs; 342 struct SubtreeReferences References = { 343 LI, SE, S, ValueMap, Values, SCEVs, getBlockGenerator(), nullptr}; 344 345 for (const auto &I : IDToValue) 346 Values.insert(I.second); 347 348 // NOTE: this is populated in IslNodeBuilder::addParameters 349 for (const auto &I : OutsideLoopIterations) 350 Values.insert(cast<SCEVUnknown>(I.second)->getValue()); 351 352 isl::union_set Schedule = getScheduleForAstNode(For).domain(); 353 addReferencesFromStmtUnionSet(Schedule, References); 354 355 for (const SCEV *Expr : SCEVs) { 356 findValues(Expr, SE, Values); 357 findLoops(Expr, Loops); 358 } 359 360 Values.remove_if([](const Value *V) { return isa<GlobalValue>(V); }); 361 362 /// Note: Code generation of induction variables of loops outside Scops 363 /// 364 /// Remove loops that contain the scop or that are part of the scop, as they 365 /// are considered local. This leaves only loops that are before the scop, but 366 /// do not contain the scop itself. 367 /// We ignore loops perfectly contained in the Scop because these are already 368 /// generated at `IslNodeBuilder::addParameters`. These `Loops` are loops 369 /// whose induction variables are referred to by the Scop, but the Scop is not 370 /// fully contained in these Loops. Since there can be many of these, 371 /// we choose to codegen these on-demand. 372 /// @see IslNodeBuilder::materializeNonScopLoopInductionVariable. 373 Loops.remove_if([this](const Loop *L) { 374 return S.contains(L) || L->contains(S.getEntry()); 375 }); 376 377 // Contains Values that may need to be replaced with other values 378 // due to replacements from the ValueMap. We should make sure 379 // that we return correctly remapped values. 380 // NOTE: this code path is tested by: 381 // 1. test/Isl/CodeGen/OpenMP/single_loop_with_loop_invariant_baseptr.ll 382 // 2. test/Isl/CodeGen/OpenMP/loop-body-references-outer-values-3.ll 383 SetVector<Value *> ReplacedValues; 384 for (Value *V : Values) { 385 ReplacedValues.insert(getLatestValue(V)); 386 } 387 Values = ReplacedValues; 388 } 389 390 void IslNodeBuilder::updateValues(ValueMapT &NewValues) { 391 SmallPtrSet<Value *, 5> Inserted; 392 393 for (const auto &I : IDToValue) { 394 IDToValue[I.first] = NewValues[I.second]; 395 Inserted.insert(I.second); 396 } 397 398 for (const auto &I : NewValues) { 399 if (Inserted.count(I.first)) 400 continue; 401 402 ValueMap[I.first] = I.second; 403 } 404 } 405 406 Value *IslNodeBuilder::getLatestValue(Value *Original) const { 407 auto It = ValueMap.find(Original); 408 if (It == ValueMap.end()) 409 return Original; 410 return It->second; 411 } 412 413 void IslNodeBuilder::createUserVector(__isl_take isl_ast_node *User, 414 std::vector<Value *> &IVS, 415 __isl_take isl_id *IteratorID, 416 __isl_take isl_union_map *Schedule) { 417 isl_ast_expr *Expr = isl_ast_node_user_get_expr(User); 418 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0); 419 isl_id *Id = isl_ast_expr_get_id(StmtExpr); 420 isl_ast_expr_free(StmtExpr); 421 ScopStmt *Stmt = (ScopStmt *)isl_id_get_user(Id); 422 std::vector<LoopToScevMapT> VLTS(IVS.size()); 423 424 isl_union_set *Domain = isl_union_set_from_set(Stmt->getDomain().release()); 425 Schedule = isl_union_map_intersect_domain(Schedule, Domain); 426 isl_map *S = isl_map_from_union_map(Schedule); 427 428 auto *NewAccesses = createNewAccesses(Stmt, User); 429 createSubstitutionsVector(Expr, Stmt, VLTS, IVS, IteratorID); 430 VectorBlockGenerator::generate(BlockGen, *Stmt, VLTS, S, NewAccesses); 431 isl_id_to_ast_expr_free(NewAccesses); 432 isl_map_free(S); 433 isl_id_free(Id); 434 isl_ast_node_free(User); 435 } 436 437 void IslNodeBuilder::createMark(__isl_take isl_ast_node *Node) { 438 auto *Id = isl_ast_node_mark_get_id(Node); 439 auto Child = isl_ast_node_mark_get_node(Node); 440 isl_ast_node_free(Node); 441 // If a child node of a 'SIMD mark' is a loop that has a single iteration, 442 // it will be optimized away and we should skip it. 443 if (strcmp(isl_id_get_name(Id), "SIMD") == 0 && 444 isl_ast_node_get_type(Child) == isl_ast_node_for) { 445 bool Vector = PollyVectorizerChoice == VECTORIZER_POLLY; 446 int VectorWidth = 447 getNumberOfIterations(isl::manage_copy(Child).as<isl::ast_node_for>()); 448 if (Vector && 1 < VectorWidth && VectorWidth <= 16) 449 createForVector(Child, VectorWidth); 450 else 451 createForSequential(isl::manage(Child).as<isl::ast_node_for>(), true); 452 isl_id_free(Id); 453 return; 454 } 455 456 BandAttr *ChildLoopAttr = getLoopAttr(isl::manage_copy(Id)); 457 BandAttr *AncestorLoopAttr; 458 if (ChildLoopAttr) { 459 // Save current LoopAttr environment to restore again when leaving this 460 // subtree. This means there was no loop between the ancestor LoopAttr and 461 // this mark, i.e. the ancestor LoopAttr did not directly mark a loop. This 462 // can happen e.g. if the AST build peeled or unrolled the loop. 463 AncestorLoopAttr = Annotator.getStagingAttrEnv(); 464 465 Annotator.getStagingAttrEnv() = ChildLoopAttr; 466 } 467 468 create(Child); 469 470 if (ChildLoopAttr) { 471 assert(Annotator.getStagingAttrEnv() == ChildLoopAttr && 472 "Nest must not overwrite loop attr environment"); 473 Annotator.getStagingAttrEnv() = AncestorLoopAttr; 474 } 475 476 isl_id_free(Id); 477 } 478 479 void IslNodeBuilder::createForVector(__isl_take isl_ast_node *For, 480 int VectorWidth) { 481 isl_ast_node *Body = isl_ast_node_for_get_body(For); 482 isl_ast_expr *Init = isl_ast_node_for_get_init(For); 483 isl_ast_expr *Inc = isl_ast_node_for_get_inc(For); 484 isl_ast_expr *Iterator = isl_ast_node_for_get_iterator(For); 485 isl_id *IteratorID = isl_ast_expr_get_id(Iterator); 486 487 Value *ValueLB = ExprBuilder.create(Init); 488 Value *ValueInc = ExprBuilder.create(Inc); 489 490 Type *MaxType = ExprBuilder.getType(Iterator); 491 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType()); 492 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType()); 493 494 if (MaxType != ValueLB->getType()) 495 ValueLB = Builder.CreateSExt(ValueLB, MaxType); 496 if (MaxType != ValueInc->getType()) 497 ValueInc = Builder.CreateSExt(ValueInc, MaxType); 498 499 std::vector<Value *> IVS(VectorWidth); 500 IVS[0] = ValueLB; 501 502 for (int i = 1; i < VectorWidth; i++) 503 IVS[i] = Builder.CreateAdd(IVS[i - 1], ValueInc, "p_vector_iv"); 504 505 isl::union_map Schedule = getScheduleForAstNode(isl::manage_copy(For)); 506 assert(!Schedule.is_null() && 507 "For statement annotation does not contain its schedule"); 508 509 IDToValue[IteratorID] = ValueLB; 510 511 switch (isl_ast_node_get_type(Body)) { 512 case isl_ast_node_user: 513 createUserVector(Body, IVS, isl_id_copy(IteratorID), Schedule.copy()); 514 break; 515 case isl_ast_node_block: { 516 isl_ast_node_list *List = isl_ast_node_block_get_children(Body); 517 518 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i) 519 createUserVector(isl_ast_node_list_get_ast_node(List, i), IVS, 520 isl_id_copy(IteratorID), Schedule.copy()); 521 522 isl_ast_node_free(Body); 523 isl_ast_node_list_free(List); 524 break; 525 } 526 default: 527 isl_ast_node_dump(Body); 528 llvm_unreachable("Unhandled isl_ast_node in vectorizer"); 529 } 530 531 IDToValue.erase(IDToValue.find(IteratorID)); 532 isl_id_free(IteratorID); 533 534 isl_ast_node_free(For); 535 isl_ast_expr_free(Iterator); 536 537 VectorLoops++; 538 } 539 540 /// Restore the initial ordering of dimensions of the band node 541 /// 542 /// In case the band node represents all the dimensions of the iteration 543 /// domain, recreate the band node to restore the initial ordering of the 544 /// dimensions. 545 /// 546 /// @param Node The band node to be modified. 547 /// @return The modified schedule node. 548 static bool IsLoopVectorizerDisabled(isl::ast_node_for Node) { 549 assert(isl_ast_node_get_type(Node.get()) == isl_ast_node_for); 550 isl::ast_node Body = Node.body(); 551 if (isl_ast_node_get_type(Body.get()) != isl_ast_node_mark) 552 return false; 553 554 isl::ast_node_mark BodyMark = Body.as<isl::ast_node_mark>(); 555 auto Id = BodyMark.id(); 556 if (strcmp(Id.get_name().c_str(), "Loop Vectorizer Disabled") == 0) 557 return true; 558 return false; 559 } 560 561 void IslNodeBuilder::createForSequential(isl::ast_node_for For, 562 bool MarkParallel) { 563 Value *ValueLB, *ValueUB, *ValueInc; 564 Type *MaxType; 565 BasicBlock *ExitBlock; 566 Value *IV; 567 CmpInst::Predicate Predicate; 568 569 bool LoopVectorizerDisabled = IsLoopVectorizerDisabled(For); 570 571 isl::ast_node Body = For.body(); 572 573 // isl_ast_node_for_is_degenerate(For) 574 // 575 // TODO: For degenerated loops we could generate a plain assignment. 576 // However, for now we just reuse the logic for normal loops, which will 577 // create a loop with a single iteration. 578 579 isl::ast_expr Init = For.init(); 580 isl::ast_expr Inc = For.inc(); 581 isl::ast_expr Iterator = For.iterator(); 582 isl::id IteratorID = Iterator.get_id(); 583 isl::ast_expr UB = getUpperBound(For, Predicate); 584 585 ValueLB = ExprBuilder.create(Init.release()); 586 ValueUB = ExprBuilder.create(UB.release()); 587 ValueInc = ExprBuilder.create(Inc.release()); 588 589 MaxType = ExprBuilder.getType(Iterator.get()); 590 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType()); 591 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType()); 592 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType()); 593 594 if (MaxType != ValueLB->getType()) 595 ValueLB = Builder.CreateSExt(ValueLB, MaxType); 596 if (MaxType != ValueUB->getType()) 597 ValueUB = Builder.CreateSExt(ValueUB, MaxType); 598 if (MaxType != ValueInc->getType()) 599 ValueInc = Builder.CreateSExt(ValueInc, MaxType); 600 601 // If we can show that LB <Predicate> UB holds at least once, we can 602 // omit the GuardBB in front of the loop. 603 bool UseGuardBB = 604 !SE.isKnownPredicate(Predicate, SE.getSCEV(ValueLB), SE.getSCEV(ValueUB)); 605 IV = createLoop(ValueLB, ValueUB, ValueInc, Builder, LI, DT, ExitBlock, 606 Predicate, &Annotator, MarkParallel, UseGuardBB, 607 LoopVectorizerDisabled); 608 IDToValue[IteratorID.get()] = IV; 609 610 create(Body.release()); 611 612 Annotator.popLoop(MarkParallel); 613 614 IDToValue.erase(IDToValue.find(IteratorID.get())); 615 616 Builder.SetInsertPoint(&ExitBlock->front()); 617 618 SequentialLoops++; 619 } 620 621 /// Remove the BBs contained in a (sub)function from the dominator tree. 622 /// 623 /// This function removes the basic blocks that are part of a subfunction from 624 /// the dominator tree. Specifically, when generating code it may happen that at 625 /// some point the code generation continues in a new sub-function (e.g., when 626 /// generating OpenMP code). The basic blocks that are created in this 627 /// sub-function are then still part of the dominator tree of the original 628 /// function, such that the dominator tree reaches over function boundaries. 629 /// This is not only incorrect, but also causes crashes. This function now 630 /// removes from the dominator tree all basic blocks that are dominated (and 631 /// consequently reachable) from the entry block of this (sub)function. 632 /// 633 /// FIXME: A LLVM (function or region) pass should not touch anything outside of 634 /// the function/region it runs on. Hence, the pure need for this function shows 635 /// that we do not comply to this rule. At the moment, this does not cause any 636 /// issues, but we should be aware that such issues may appear. Unfortunately 637 /// the current LLVM pass infrastructure does not allow to make Polly a module 638 /// or call-graph pass to solve this issue, as such a pass would not have access 639 /// to the per-function analyses passes needed by Polly. A future pass manager 640 /// infrastructure is supposed to enable such kind of access possibly allowing 641 /// us to create a cleaner solution here. 642 /// 643 /// FIXME: Instead of adding the dominance information and then dropping it 644 /// later on, we should try to just not add it in the first place. This requires 645 /// some careful testing to make sure this does not break in interaction with 646 /// the SCEVBuilder and SplitBlock which may rely on the dominator tree or 647 /// which may try to update it. 648 /// 649 /// @param F The function which contains the BBs to removed. 650 /// @param DT The dominator tree from which to remove the BBs. 651 static void removeSubFuncFromDomTree(Function *F, DominatorTree &DT) { 652 DomTreeNode *N = DT.getNode(&F->getEntryBlock()); 653 std::vector<BasicBlock *> Nodes; 654 655 // We can only remove an element from the dominator tree, if all its children 656 // have been removed. To ensure this we obtain the list of nodes to remove 657 // using a post-order tree traversal. 658 for (po_iterator<DomTreeNode *> I = po_begin(N), E = po_end(N); I != E; ++I) 659 Nodes.push_back(I->getBlock()); 660 661 for (BasicBlock *BB : Nodes) 662 DT.eraseNode(BB); 663 } 664 665 void IslNodeBuilder::createForParallel(__isl_take isl_ast_node *For) { 666 isl_ast_node *Body; 667 isl_ast_expr *Init, *Inc, *Iterator, *UB; 668 isl_id *IteratorID; 669 Value *ValueLB, *ValueUB, *ValueInc; 670 Type *MaxType; 671 Value *IV; 672 CmpInst::Predicate Predicate; 673 674 // The preamble of parallel code interacts different than normal code with 675 // e.g., scalar initialization. Therefore, we ensure the parallel code is 676 // separated from the last basic block. 677 BasicBlock *ParBB = SplitBlock(Builder.GetInsertBlock(), 678 &*Builder.GetInsertPoint(), &DT, &LI); 679 ParBB->setName("polly.parallel.for"); 680 Builder.SetInsertPoint(&ParBB->front()); 681 682 Body = isl_ast_node_for_get_body(For); 683 Init = isl_ast_node_for_get_init(For); 684 Inc = isl_ast_node_for_get_inc(For); 685 Iterator = isl_ast_node_for_get_iterator(For); 686 IteratorID = isl_ast_expr_get_id(Iterator); 687 UB = getUpperBound(isl::manage_copy(For).as<isl::ast_node_for>(), Predicate) 688 .release(); 689 690 ValueLB = ExprBuilder.create(Init); 691 ValueUB = ExprBuilder.create(UB); 692 ValueInc = ExprBuilder.create(Inc); 693 694 // OpenMP always uses SLE. In case the isl generated AST uses a SLT 695 // expression, we need to adjust the loop bound by one. 696 if (Predicate == CmpInst::ICMP_SLT) 697 ValueUB = Builder.CreateAdd( 698 ValueUB, Builder.CreateSExt(Builder.getTrue(), ValueUB->getType())); 699 700 MaxType = ExprBuilder.getType(Iterator); 701 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType()); 702 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType()); 703 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType()); 704 705 if (MaxType != ValueLB->getType()) 706 ValueLB = Builder.CreateSExt(ValueLB, MaxType); 707 if (MaxType != ValueUB->getType()) 708 ValueUB = Builder.CreateSExt(ValueUB, MaxType); 709 if (MaxType != ValueInc->getType()) 710 ValueInc = Builder.CreateSExt(ValueInc, MaxType); 711 712 BasicBlock::iterator LoopBody; 713 714 SetVector<Value *> SubtreeValues; 715 SetVector<const Loop *> Loops; 716 717 getReferencesInSubtree(isl::manage_copy(For), SubtreeValues, Loops); 718 719 // Create for all loops we depend on values that contain the current loop 720 // iteration. These values are necessary to generate code for SCEVs that 721 // depend on such loops. As a result we need to pass them to the subfunction. 722 // See [Code generation of induction variables of loops outside Scops] 723 for (const Loop *L : Loops) { 724 Value *LoopInductionVar = materializeNonScopLoopInductionVariable(L); 725 SubtreeValues.insert(LoopInductionVar); 726 } 727 728 ValueMapT NewValues; 729 730 std::unique_ptr<ParallelLoopGenerator> ParallelLoopGenPtr; 731 732 switch (PollyOmpBackend) { 733 case OpenMPBackend::GNU: 734 ParallelLoopGenPtr.reset( 735 new ParallelLoopGeneratorGOMP(Builder, LI, DT, DL)); 736 break; 737 case OpenMPBackend::LLVM: 738 ParallelLoopGenPtr.reset(new ParallelLoopGeneratorKMP(Builder, LI, DT, DL)); 739 break; 740 } 741 742 IV = ParallelLoopGenPtr->createParallelLoop( 743 ValueLB, ValueUB, ValueInc, SubtreeValues, NewValues, &LoopBody); 744 BasicBlock::iterator AfterLoop = Builder.GetInsertPoint(); 745 Builder.SetInsertPoint(&*LoopBody); 746 747 // Remember the parallel subfunction 748 ParallelSubfunctions.push_back(LoopBody->getFunction()); 749 750 // Save the current values. 751 auto ValueMapCopy = ValueMap; 752 IslExprBuilder::IDToValueTy IDToValueCopy = IDToValue; 753 754 updateValues(NewValues); 755 IDToValue[IteratorID] = IV; 756 757 ValueMapT NewValuesReverse; 758 759 for (auto P : NewValues) 760 NewValuesReverse[P.second] = P.first; 761 762 Annotator.addAlternativeAliasBases(NewValuesReverse); 763 764 create(Body); 765 766 Annotator.resetAlternativeAliasBases(); 767 // Restore the original values. 768 ValueMap = ValueMapCopy; 769 IDToValue = IDToValueCopy; 770 771 Builder.SetInsertPoint(&*AfterLoop); 772 removeSubFuncFromDomTree((*LoopBody).getParent()->getParent(), DT); 773 774 for (const Loop *L : Loops) 775 OutsideLoopIterations.erase(L); 776 777 isl_ast_node_free(For); 778 isl_ast_expr_free(Iterator); 779 isl_id_free(IteratorID); 780 781 ParallelLoops++; 782 } 783 784 /// Return whether any of @p Node's statements contain partial accesses. 785 /// 786 /// Partial accesses are not supported by Polly's vector code generator. 787 static bool hasPartialAccesses(__isl_take isl_ast_node *Node) { 788 return isl_ast_node_foreach_descendant_top_down( 789 Node, 790 [](isl_ast_node *Node, void *User) -> isl_bool { 791 if (isl_ast_node_get_type(Node) != isl_ast_node_user) 792 return isl_bool_true; 793 794 isl::ast_expr Expr = 795 isl::manage(isl_ast_node_user_get_expr(Node)); 796 isl::ast_expr StmtExpr = Expr.get_op_arg(0); 797 isl::id Id = StmtExpr.get_id(); 798 799 ScopStmt *Stmt = 800 static_cast<ScopStmt *>(isl_id_get_user(Id.get())); 801 isl::set StmtDom = Stmt->getDomain(); 802 for (auto *MA : *Stmt) { 803 if (MA->isLatestPartialAccess()) 804 return isl_bool_error; 805 } 806 return isl_bool_true; 807 }, 808 nullptr) == isl_stat_error; 809 } 810 811 void IslNodeBuilder::createFor(__isl_take isl_ast_node *For) { 812 bool Vector = PollyVectorizerChoice == VECTORIZER_POLLY; 813 814 if (Vector && IslAstInfo::isInnermostParallel(isl::manage_copy(For)) && 815 !IslAstInfo::isReductionParallel(isl::manage_copy(For))) { 816 int VectorWidth = 817 getNumberOfIterations(isl::manage_copy(For).as<isl::ast_node_for>()); 818 if (1 < VectorWidth && VectorWidth <= 16 && !hasPartialAccesses(For)) { 819 createForVector(For, VectorWidth); 820 return; 821 } 822 } 823 824 if (IslAstInfo::isExecutedInParallel(isl::manage_copy(For))) { 825 createForParallel(For); 826 return; 827 } 828 bool Parallel = (IslAstInfo::isParallel(isl::manage_copy(For)) && 829 !IslAstInfo::isReductionParallel(isl::manage_copy(For))); 830 createForSequential(isl::manage(For).as<isl::ast_node_for>(), Parallel); 831 } 832 833 void IslNodeBuilder::createIf(__isl_take isl_ast_node *If) { 834 isl_ast_expr *Cond = isl_ast_node_if_get_cond(If); 835 836 Function *F = Builder.GetInsertBlock()->getParent(); 837 LLVMContext &Context = F->getContext(); 838 839 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(), 840 &*Builder.GetInsertPoint(), &DT, &LI); 841 CondBB->setName("polly.cond"); 842 BasicBlock *MergeBB = SplitBlock(CondBB, &CondBB->front(), &DT, &LI); 843 MergeBB->setName("polly.merge"); 844 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F); 845 BasicBlock *ElseBB = BasicBlock::Create(Context, "polly.else", F); 846 847 DT.addNewBlock(ThenBB, CondBB); 848 DT.addNewBlock(ElseBB, CondBB); 849 DT.changeImmediateDominator(MergeBB, CondBB); 850 851 Loop *L = LI.getLoopFor(CondBB); 852 if (L) { 853 L->addBasicBlockToLoop(ThenBB, LI); 854 L->addBasicBlockToLoop(ElseBB, LI); 855 } 856 857 CondBB->getTerminator()->eraseFromParent(); 858 859 Builder.SetInsertPoint(CondBB); 860 Value *Predicate = ExprBuilder.create(Cond); 861 Builder.CreateCondBr(Predicate, ThenBB, ElseBB); 862 Builder.SetInsertPoint(ThenBB); 863 Builder.CreateBr(MergeBB); 864 Builder.SetInsertPoint(ElseBB); 865 Builder.CreateBr(MergeBB); 866 Builder.SetInsertPoint(&ThenBB->front()); 867 868 create(isl_ast_node_if_get_then(If)); 869 870 Builder.SetInsertPoint(&ElseBB->front()); 871 872 if (isl_ast_node_if_has_else(If)) 873 create(isl_ast_node_if_get_else(If)); 874 875 Builder.SetInsertPoint(&MergeBB->front()); 876 877 isl_ast_node_free(If); 878 879 IfConditions++; 880 } 881 882 __isl_give isl_id_to_ast_expr * 883 IslNodeBuilder::createNewAccesses(ScopStmt *Stmt, 884 __isl_keep isl_ast_node *Node) { 885 isl::id_to_ast_expr NewAccesses = 886 isl::id_to_ast_expr::alloc(Stmt->getParent()->getIslCtx(), 0); 887 888 isl::ast_build Build = IslAstInfo::getBuild(isl::manage_copy(Node)); 889 assert(!Build.is_null() && "Could not obtain isl_ast_build from user node"); 890 Stmt->setAstBuild(Build); 891 892 for (auto *MA : *Stmt) { 893 if (!MA->hasNewAccessRelation()) { 894 if (PollyGenerateExpressions) { 895 if (!MA->isAffine()) 896 continue; 897 if (MA->getLatestScopArrayInfo()->getBasePtrOriginSAI()) 898 continue; 899 900 auto *BasePtr = 901 dyn_cast<Instruction>(MA->getLatestScopArrayInfo()->getBasePtr()); 902 if (BasePtr && Stmt->getParent()->getRegion().contains(BasePtr)) 903 continue; 904 } else { 905 continue; 906 } 907 } 908 assert(MA->isAffine() && 909 "Only affine memory accesses can be code generated"); 910 911 isl::union_map Schedule = Build.get_schedule(); 912 913 #ifndef NDEBUG 914 if (MA->isRead()) { 915 auto Dom = Stmt->getDomain().release(); 916 auto SchedDom = isl_set_from_union_set(Schedule.domain().release()); 917 auto AccDom = isl_map_domain(MA->getAccessRelation().release()); 918 Dom = isl_set_intersect_params(Dom, 919 Stmt->getParent()->getContext().release()); 920 SchedDom = isl_set_intersect_params( 921 SchedDom, Stmt->getParent()->getContext().release()); 922 assert(isl_set_is_subset(SchedDom, AccDom) && 923 "Access relation not defined on full schedule domain"); 924 assert(isl_set_is_subset(Dom, AccDom) && 925 "Access relation not defined on full domain"); 926 isl_set_free(AccDom); 927 isl_set_free(SchedDom); 928 isl_set_free(Dom); 929 } 930 #endif 931 932 isl::pw_multi_aff PWAccRel = MA->applyScheduleToAccessRelation(Schedule); 933 934 // isl cannot generate an index expression for access-nothing accesses. 935 isl::set AccDomain = PWAccRel.domain(); 936 isl::set Context = S.getContext(); 937 AccDomain = AccDomain.intersect_params(Context); 938 if (AccDomain.is_empty()) 939 continue; 940 941 isl::ast_expr AccessExpr = Build.access_from(PWAccRel); 942 NewAccesses = NewAccesses.set(MA->getId(), AccessExpr); 943 } 944 945 return NewAccesses.release(); 946 } 947 948 void IslNodeBuilder::createSubstitutions(__isl_take isl_ast_expr *Expr, 949 ScopStmt *Stmt, LoopToScevMapT <S) { 950 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op && 951 "Expression of type 'op' expected"); 952 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_call && 953 "Operation of type 'call' expected"); 954 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr) - 1; ++i) { 955 isl_ast_expr *SubExpr; 956 Value *V; 957 958 SubExpr = isl_ast_expr_get_op_arg(Expr, i + 1); 959 V = ExprBuilder.create(SubExpr); 960 ScalarEvolution *SE = Stmt->getParent()->getSE(); 961 LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V); 962 } 963 964 isl_ast_expr_free(Expr); 965 } 966 967 void IslNodeBuilder::createSubstitutionsVector( 968 __isl_take isl_ast_expr *Expr, ScopStmt *Stmt, 969 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS, 970 __isl_take isl_id *IteratorID) { 971 int i = 0; 972 973 Value *OldValue = IDToValue[IteratorID]; 974 for (Value *IV : IVS) { 975 IDToValue[IteratorID] = IV; 976 createSubstitutions(isl_ast_expr_copy(Expr), Stmt, VLTS[i]); 977 i++; 978 } 979 980 IDToValue[IteratorID] = OldValue; 981 isl_id_free(IteratorID); 982 isl_ast_expr_free(Expr); 983 } 984 985 void IslNodeBuilder::generateCopyStmt( 986 ScopStmt *Stmt, __isl_keep isl_id_to_ast_expr *NewAccesses) { 987 assert(Stmt->size() == 2); 988 auto ReadAccess = Stmt->begin(); 989 auto WriteAccess = ReadAccess++; 990 assert((*ReadAccess)->isRead() && (*WriteAccess)->isMustWrite()); 991 assert((*ReadAccess)->getElementType() == (*WriteAccess)->getElementType() && 992 "Accesses use the same data type"); 993 assert((*ReadAccess)->isArrayKind() && (*WriteAccess)->isArrayKind()); 994 auto *AccessExpr = 995 isl_id_to_ast_expr_get(NewAccesses, (*ReadAccess)->getId().release()); 996 auto *LoadValue = ExprBuilder.create(AccessExpr); 997 AccessExpr = 998 isl_id_to_ast_expr_get(NewAccesses, (*WriteAccess)->getId().release()); 999 auto *StoreAddr = ExprBuilder.createAccessAddress(AccessExpr).first; 1000 Builder.CreateStore(LoadValue, StoreAddr); 1001 } 1002 1003 Value *IslNodeBuilder::materializeNonScopLoopInductionVariable(const Loop *L) { 1004 assert(OutsideLoopIterations.find(L) == OutsideLoopIterations.end() && 1005 "trying to materialize loop induction variable twice"); 1006 const SCEV *OuterLIV = SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)), 1007 SE.getUnknown(Builder.getInt64(1)), L, 1008 SCEV::FlagAnyWrap); 1009 Value *V = generateSCEV(OuterLIV); 1010 OutsideLoopIterations[L] = SE.getUnknown(V); 1011 return V; 1012 } 1013 1014 void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) { 1015 LoopToScevMapT LTS; 1016 isl_id *Id; 1017 ScopStmt *Stmt; 1018 1019 isl_ast_expr *Expr = isl_ast_node_user_get_expr(User); 1020 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0); 1021 Id = isl_ast_expr_get_id(StmtExpr); 1022 isl_ast_expr_free(StmtExpr); 1023 1024 LTS.insert(OutsideLoopIterations.begin(), OutsideLoopIterations.end()); 1025 1026 Stmt = (ScopStmt *)isl_id_get_user(Id); 1027 auto *NewAccesses = createNewAccesses(Stmt, User); 1028 if (Stmt->isCopyStmt()) { 1029 generateCopyStmt(Stmt, NewAccesses); 1030 isl_ast_expr_free(Expr); 1031 } else { 1032 createSubstitutions(Expr, Stmt, LTS); 1033 1034 if (Stmt->isBlockStmt()) 1035 BlockGen.copyStmt(*Stmt, LTS, NewAccesses); 1036 else 1037 RegionGen.copyStmt(*Stmt, LTS, NewAccesses); 1038 } 1039 1040 isl_id_to_ast_expr_free(NewAccesses); 1041 isl_ast_node_free(User); 1042 isl_id_free(Id); 1043 } 1044 1045 void IslNodeBuilder::createBlock(__isl_take isl_ast_node *Block) { 1046 isl_ast_node_list *List = isl_ast_node_block_get_children(Block); 1047 1048 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i) 1049 create(isl_ast_node_list_get_ast_node(List, i)); 1050 1051 isl_ast_node_free(Block); 1052 isl_ast_node_list_free(List); 1053 } 1054 1055 void IslNodeBuilder::create(__isl_take isl_ast_node *Node) { 1056 switch (isl_ast_node_get_type(Node)) { 1057 case isl_ast_node_error: 1058 llvm_unreachable("code generation error"); 1059 case isl_ast_node_mark: 1060 createMark(Node); 1061 return; 1062 case isl_ast_node_for: 1063 createFor(Node); 1064 return; 1065 case isl_ast_node_if: 1066 createIf(Node); 1067 return; 1068 case isl_ast_node_user: 1069 createUser(Node); 1070 return; 1071 case isl_ast_node_block: 1072 createBlock(Node); 1073 return; 1074 } 1075 1076 llvm_unreachable("Unknown isl_ast_node type"); 1077 } 1078 1079 bool IslNodeBuilder::materializeValue(isl_id *Id) { 1080 // If the Id is already mapped, skip it. 1081 if (!IDToValue.count(Id)) { 1082 auto *ParamSCEV = (const SCEV *)isl_id_get_user(Id); 1083 Value *V = nullptr; 1084 1085 // Parameters could refer to invariant loads that need to be 1086 // preloaded before we can generate code for the parameter. Thus, 1087 // check if any value referred to in ParamSCEV is an invariant load 1088 // and if so make sure its equivalence class is preloaded. 1089 SetVector<Value *> Values; 1090 findValues(ParamSCEV, SE, Values); 1091 for (auto *Val : Values) { 1092 // Check if the value is an instruction in a dead block within the SCoP 1093 // and if so do not code generate it. 1094 if (auto *Inst = dyn_cast<Instruction>(Val)) { 1095 if (S.contains(Inst)) { 1096 bool IsDead = true; 1097 1098 // Check for "undef" loads first, then if there is a statement for 1099 // the parent of Inst and lastly if the parent of Inst has an empty 1100 // domain. In the first and last case the instruction is dead but if 1101 // there is a statement or the domain is not empty Inst is not dead. 1102 auto MemInst = MemAccInst::dyn_cast(Inst); 1103 auto Address = MemInst ? MemInst.getPointerOperand() : nullptr; 1104 if (Address && SE.getUnknown(UndefValue::get(Address->getType())) == 1105 SE.getPointerBase(SE.getSCEV(Address))) { 1106 } else if (S.getStmtFor(Inst)) { 1107 IsDead = false; 1108 } else { 1109 auto *Domain = S.getDomainConditions(Inst->getParent()).release(); 1110 IsDead = isl_set_is_empty(Domain); 1111 isl_set_free(Domain); 1112 } 1113 1114 if (IsDead) { 1115 V = UndefValue::get(ParamSCEV->getType()); 1116 break; 1117 } 1118 } 1119 } 1120 1121 if (auto *IAClass = S.lookupInvariantEquivClass(Val)) { 1122 // Check if this invariant access class is empty, hence if we never 1123 // actually added a loads instruction to it. In that case it has no 1124 // (meaningful) users and we should not try to code generate it. 1125 if (IAClass->InvariantAccesses.empty()) 1126 V = UndefValue::get(ParamSCEV->getType()); 1127 1128 if (!preloadInvariantEquivClass(*IAClass)) { 1129 isl_id_free(Id); 1130 return false; 1131 } 1132 } 1133 } 1134 1135 V = V ? V : generateSCEV(ParamSCEV); 1136 IDToValue[Id] = V; 1137 } 1138 1139 isl_id_free(Id); 1140 return true; 1141 } 1142 1143 bool IslNodeBuilder::materializeParameters(isl_set *Set) { 1144 for (unsigned i = 0, e = isl_set_dim(Set, isl_dim_param); i < e; ++i) { 1145 if (!isl_set_involves_dims(Set, isl_dim_param, i, 1)) 1146 continue; 1147 isl_id *Id = isl_set_get_dim_id(Set, isl_dim_param, i); 1148 if (!materializeValue(Id)) 1149 return false; 1150 } 1151 return true; 1152 } 1153 1154 bool IslNodeBuilder::materializeParameters() { 1155 for (const SCEV *Param : S.parameters()) { 1156 isl_id *Id = S.getIdForParam(Param).release(); 1157 if (!materializeValue(Id)) 1158 return false; 1159 } 1160 return true; 1161 } 1162 1163 /// Generate the computation of the size of the outermost dimension from the 1164 /// Fortran array descriptor (in this case, `@g_arr`). The final `%size` 1165 /// contains the size of the array. 1166 /// 1167 /// %arrty = type { i8*, i64, i64, [3 x %desc.dimensionty] } 1168 /// %desc.dimensionty = type { i64, i64, i64 } 1169 /// @g_arr = global %arrty zeroinitializer, align 32 1170 /// ... 1171 /// %0 = load i64, i64* getelementptr inbounds 1172 /// (%arrty, %arrty* @g_arr, i64 0, i32 3, i64 0, i32 2) 1173 /// %1 = load i64, i64* getelementptr inbounds 1174 /// (%arrty, %arrty* @g_arr, i64 0, i32 3, i64 0, i32 1) 1175 /// %2 = sub nsw i64 %0, %1 1176 /// %size = add nsw i64 %2, 1 1177 static Value *buildFADOutermostDimensionLoad(Value *GlobalDescriptor, 1178 PollyIRBuilder &Builder, 1179 std::string ArrayName) { 1180 assert(GlobalDescriptor && "invalid global descriptor given"); 1181 Type *Ty = GlobalDescriptor->getType()->getPointerElementType(); 1182 1183 Value *endIdx[4] = {Builder.getInt64(0), Builder.getInt32(3), 1184 Builder.getInt64(0), Builder.getInt32(2)}; 1185 Value *endPtr = Builder.CreateInBoundsGEP(Ty, GlobalDescriptor, endIdx, 1186 ArrayName + "_end_ptr"); 1187 Type *type = cast<GEPOperator>(endPtr)->getResultElementType(); 1188 assert(isa<IntegerType>(type) && "expected type of end to be integral"); 1189 1190 Value *end = Builder.CreateLoad(type, endPtr, ArrayName + "_end"); 1191 1192 Value *beginIdx[4] = {Builder.getInt64(0), Builder.getInt32(3), 1193 Builder.getInt64(0), Builder.getInt32(1)}; 1194 Value *beginPtr = Builder.CreateInBoundsGEP(Ty, GlobalDescriptor, beginIdx, 1195 ArrayName + "_begin_ptr"); 1196 Value *begin = Builder.CreateLoad(type, beginPtr, ArrayName + "_begin"); 1197 1198 Value *size = 1199 Builder.CreateNSWSub(end, begin, ArrayName + "_end_begin_delta"); 1200 1201 size = Builder.CreateNSWAdd( 1202 end, ConstantInt::get(type, 1, /* signed = */ true), ArrayName + "_size"); 1203 1204 return size; 1205 } 1206 1207 bool IslNodeBuilder::materializeFortranArrayOutermostDimension() { 1208 for (ScopArrayInfo *Array : S.arrays()) { 1209 if (Array->getNumberOfDimensions() == 0) 1210 continue; 1211 1212 Value *FAD = Array->getFortranArrayDescriptor(); 1213 if (!FAD) 1214 continue; 1215 1216 isl_pw_aff *ParametricPwAff = Array->getDimensionSizePw(0).release(); 1217 assert(ParametricPwAff && "parametric pw_aff corresponding " 1218 "to outermost dimension does not " 1219 "exist"); 1220 1221 isl_id *Id = isl_pw_aff_get_dim_id(ParametricPwAff, isl_dim_param, 0); 1222 isl_pw_aff_free(ParametricPwAff); 1223 1224 assert(Id && "pw_aff is not parametric"); 1225 1226 if (IDToValue.count(Id)) { 1227 isl_id_free(Id); 1228 continue; 1229 } 1230 1231 Value *FinalValue = 1232 buildFADOutermostDimensionLoad(FAD, Builder, Array->getName()); 1233 assert(FinalValue && "unable to build Fortran array " 1234 "descriptor load of outermost dimension"); 1235 IDToValue[Id] = FinalValue; 1236 isl_id_free(Id); 1237 } 1238 return true; 1239 } 1240 1241 Value *IslNodeBuilder::preloadUnconditionally(isl_set *AccessRange, 1242 isl_ast_build *Build, 1243 Instruction *AccInst) { 1244 isl_pw_multi_aff *PWAccRel = isl_pw_multi_aff_from_set(AccessRange); 1245 isl_ast_expr *Access = 1246 isl_ast_build_access_from_pw_multi_aff(Build, PWAccRel); 1247 auto *Address = isl_ast_expr_address_of(Access); 1248 auto *AddressValue = ExprBuilder.create(Address); 1249 Value *PreloadVal; 1250 1251 // Correct the type as the SAI might have a different type than the user 1252 // expects, especially if the base pointer is a struct. 1253 Type *Ty = AccInst->getType(); 1254 1255 auto *Ptr = AddressValue; 1256 auto Name = Ptr->getName(); 1257 auto AS = Ptr->getType()->getPointerAddressSpace(); 1258 Ptr = Builder.CreatePointerCast(Ptr, Ty->getPointerTo(AS), Name + ".cast"); 1259 PreloadVal = Builder.CreateLoad(Ty, Ptr, Name + ".load"); 1260 if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal)) 1261 PreloadInst->setAlignment(cast<LoadInst>(AccInst)->getAlign()); 1262 1263 // TODO: This is only a hot fix for SCoP sequences that use the same load 1264 // instruction contained and hoisted by one of the SCoPs. 1265 if (SE.isSCEVable(Ty)) 1266 SE.forgetValue(AccInst); 1267 1268 return PreloadVal; 1269 } 1270 1271 Value *IslNodeBuilder::preloadInvariantLoad(const MemoryAccess &MA, 1272 isl_set *Domain) { 1273 isl_set *AccessRange = isl_map_range(MA.getAddressFunction().release()); 1274 AccessRange = isl_set_gist_params(AccessRange, S.getContext().release()); 1275 1276 if (!materializeParameters(AccessRange)) { 1277 isl_set_free(AccessRange); 1278 isl_set_free(Domain); 1279 return nullptr; 1280 } 1281 1282 auto *Build = 1283 isl_ast_build_from_context(isl_set_universe(S.getParamSpace().release())); 1284 isl_set *Universe = isl_set_universe(isl_set_get_space(Domain)); 1285 bool AlwaysExecuted = isl_set_is_equal(Domain, Universe); 1286 isl_set_free(Universe); 1287 1288 Instruction *AccInst = MA.getAccessInstruction(); 1289 Type *AccInstTy = AccInst->getType(); 1290 1291 Value *PreloadVal = nullptr; 1292 if (AlwaysExecuted) { 1293 PreloadVal = preloadUnconditionally(AccessRange, Build, AccInst); 1294 isl_ast_build_free(Build); 1295 isl_set_free(Domain); 1296 return PreloadVal; 1297 } 1298 1299 if (!materializeParameters(Domain)) { 1300 isl_ast_build_free(Build); 1301 isl_set_free(AccessRange); 1302 isl_set_free(Domain); 1303 return nullptr; 1304 } 1305 1306 isl_ast_expr *DomainCond = isl_ast_build_expr_from_set(Build, Domain); 1307 Domain = nullptr; 1308 1309 ExprBuilder.setTrackOverflow(true); 1310 Value *Cond = ExprBuilder.create(DomainCond); 1311 Value *OverflowHappened = Builder.CreateNot(ExprBuilder.getOverflowState(), 1312 "polly.preload.cond.overflown"); 1313 Cond = Builder.CreateAnd(Cond, OverflowHappened, "polly.preload.cond.result"); 1314 ExprBuilder.setTrackOverflow(false); 1315 1316 if (!Cond->getType()->isIntegerTy(1)) 1317 Cond = Builder.CreateIsNotNull(Cond); 1318 1319 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(), 1320 &*Builder.GetInsertPoint(), &DT, &LI); 1321 CondBB->setName("polly.preload.cond"); 1322 1323 BasicBlock *MergeBB = SplitBlock(CondBB, &CondBB->front(), &DT, &LI); 1324 MergeBB->setName("polly.preload.merge"); 1325 1326 Function *F = Builder.GetInsertBlock()->getParent(); 1327 LLVMContext &Context = F->getContext(); 1328 BasicBlock *ExecBB = BasicBlock::Create(Context, "polly.preload.exec", F); 1329 1330 DT.addNewBlock(ExecBB, CondBB); 1331 if (Loop *L = LI.getLoopFor(CondBB)) 1332 L->addBasicBlockToLoop(ExecBB, LI); 1333 1334 auto *CondBBTerminator = CondBB->getTerminator(); 1335 Builder.SetInsertPoint(CondBBTerminator); 1336 Builder.CreateCondBr(Cond, ExecBB, MergeBB); 1337 CondBBTerminator->eraseFromParent(); 1338 1339 Builder.SetInsertPoint(ExecBB); 1340 Builder.CreateBr(MergeBB); 1341 1342 Builder.SetInsertPoint(ExecBB->getTerminator()); 1343 Value *PreAccInst = preloadUnconditionally(AccessRange, Build, AccInst); 1344 Builder.SetInsertPoint(MergeBB->getTerminator()); 1345 auto *MergePHI = Builder.CreatePHI( 1346 AccInstTy, 2, "polly.preload." + AccInst->getName() + ".merge"); 1347 PreloadVal = MergePHI; 1348 1349 if (!PreAccInst) { 1350 PreloadVal = nullptr; 1351 PreAccInst = UndefValue::get(AccInstTy); 1352 } 1353 1354 MergePHI->addIncoming(PreAccInst, ExecBB); 1355 MergePHI->addIncoming(Constant::getNullValue(AccInstTy), CondBB); 1356 1357 isl_ast_build_free(Build); 1358 return PreloadVal; 1359 } 1360 1361 bool IslNodeBuilder::preloadInvariantEquivClass( 1362 InvariantEquivClassTy &IAClass) { 1363 // For an equivalence class of invariant loads we pre-load the representing 1364 // element with the unified execution context. However, we have to map all 1365 // elements of the class to the one preloaded load as they are referenced 1366 // during the code generation and therefor need to be mapped. 1367 const MemoryAccessList &MAs = IAClass.InvariantAccesses; 1368 if (MAs.empty()) 1369 return true; 1370 1371 MemoryAccess *MA = MAs.front(); 1372 assert(MA->isArrayKind() && MA->isRead()); 1373 1374 // If the access function was already mapped, the preload of this equivalence 1375 // class was triggered earlier already and doesn't need to be done again. 1376 if (ValueMap.count(MA->getAccessInstruction())) 1377 return true; 1378 1379 // Check for recursion which can be caused by additional constraints, e.g., 1380 // non-finite loop constraints. In such a case we have to bail out and insert 1381 // a "false" runtime check that will cause the original code to be executed. 1382 auto PtrId = std::make_pair(IAClass.IdentifyingPointer, IAClass.AccessType); 1383 if (!PreloadedPtrs.insert(PtrId).second) 1384 return false; 1385 1386 // The execution context of the IAClass. 1387 isl::set &ExecutionCtx = IAClass.ExecutionContext; 1388 1389 // If the base pointer of this class is dependent on another one we have to 1390 // make sure it was preloaded already. 1391 auto *SAI = MA->getScopArrayInfo(); 1392 if (auto *BaseIAClass = S.lookupInvariantEquivClass(SAI->getBasePtr())) { 1393 if (!preloadInvariantEquivClass(*BaseIAClass)) 1394 return false; 1395 1396 // After we preloaded the BaseIAClass we adjusted the BaseExecutionCtx and 1397 // we need to refine the ExecutionCtx. 1398 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext; 1399 ExecutionCtx = ExecutionCtx.intersect(BaseExecutionCtx); 1400 } 1401 1402 // If the size of a dimension is dependent on another class, make sure it is 1403 // preloaded. 1404 for (unsigned i = 1, e = SAI->getNumberOfDimensions(); i < e; ++i) { 1405 const SCEV *Dim = SAI->getDimensionSize(i); 1406 SetVector<Value *> Values; 1407 findValues(Dim, SE, Values); 1408 for (auto *Val : Values) { 1409 if (auto *BaseIAClass = S.lookupInvariantEquivClass(Val)) { 1410 if (!preloadInvariantEquivClass(*BaseIAClass)) 1411 return false; 1412 1413 // After we preloaded the BaseIAClass we adjusted the BaseExecutionCtx 1414 // and we need to refine the ExecutionCtx. 1415 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext; 1416 ExecutionCtx = ExecutionCtx.intersect(BaseExecutionCtx); 1417 } 1418 } 1419 } 1420 1421 Instruction *AccInst = MA->getAccessInstruction(); 1422 Type *AccInstTy = AccInst->getType(); 1423 1424 Value *PreloadVal = preloadInvariantLoad(*MA, ExecutionCtx.copy()); 1425 if (!PreloadVal) 1426 return false; 1427 1428 for (const MemoryAccess *MA : MAs) { 1429 Instruction *MAAccInst = MA->getAccessInstruction(); 1430 assert(PreloadVal->getType() == MAAccInst->getType()); 1431 ValueMap[MAAccInst] = PreloadVal; 1432 } 1433 1434 if (SE.isSCEVable(AccInstTy)) { 1435 isl_id *ParamId = S.getIdForParam(SE.getSCEV(AccInst)).release(); 1436 if (ParamId) 1437 IDToValue[ParamId] = PreloadVal; 1438 isl_id_free(ParamId); 1439 } 1440 1441 BasicBlock *EntryBB = &Builder.GetInsertBlock()->getParent()->getEntryBlock(); 1442 auto *Alloca = new AllocaInst(AccInstTy, DL.getAllocaAddrSpace(), 1443 AccInst->getName() + ".preload.s2a", 1444 &*EntryBB->getFirstInsertionPt()); 1445 Builder.CreateStore(PreloadVal, Alloca); 1446 ValueMapT PreloadedPointer; 1447 PreloadedPointer[PreloadVal] = AccInst; 1448 Annotator.addAlternativeAliasBases(PreloadedPointer); 1449 1450 for (auto *DerivedSAI : SAI->getDerivedSAIs()) { 1451 Value *BasePtr = DerivedSAI->getBasePtr(); 1452 1453 for (const MemoryAccess *MA : MAs) { 1454 // As the derived SAI information is quite coarse, any load from the 1455 // current SAI could be the base pointer of the derived SAI, however we 1456 // should only change the base pointer of the derived SAI if we actually 1457 // preloaded it. 1458 if (BasePtr == MA->getOriginalBaseAddr()) { 1459 assert(BasePtr->getType() == PreloadVal->getType()); 1460 DerivedSAI->setBasePtr(PreloadVal); 1461 } 1462 1463 // For scalar derived SAIs we remap the alloca used for the derived value. 1464 if (BasePtr == MA->getAccessInstruction()) 1465 ScalarMap[DerivedSAI] = Alloca; 1466 } 1467 } 1468 1469 for (const MemoryAccess *MA : MAs) { 1470 Instruction *MAAccInst = MA->getAccessInstruction(); 1471 // Use the escape system to get the correct value to users outside the SCoP. 1472 BlockGenerator::EscapeUserVectorTy EscapeUsers; 1473 for (auto *U : MAAccInst->users()) 1474 if (Instruction *UI = dyn_cast<Instruction>(U)) 1475 if (!S.contains(UI)) 1476 EscapeUsers.push_back(UI); 1477 1478 if (EscapeUsers.empty()) 1479 continue; 1480 1481 EscapeMap[MA->getAccessInstruction()] = 1482 std::make_pair(Alloca, std::move(EscapeUsers)); 1483 } 1484 1485 return true; 1486 } 1487 1488 void IslNodeBuilder::allocateNewArrays(BBPair StartExitBlocks) { 1489 for (auto &SAI : S.arrays()) { 1490 if (SAI->getBasePtr()) 1491 continue; 1492 1493 assert(SAI->getNumberOfDimensions() > 0 && SAI->getDimensionSize(0) && 1494 "The size of the outermost dimension is used to declare newly " 1495 "created arrays that require memory allocation."); 1496 1497 Type *NewArrayType = nullptr; 1498 1499 // Get the size of the array = size(dim_1)*...*size(dim_n) 1500 uint64_t ArraySizeInt = 1; 1501 for (int i = SAI->getNumberOfDimensions() - 1; i >= 0; i--) { 1502 auto *DimSize = SAI->getDimensionSize(i); 1503 unsigned UnsignedDimSize = static_cast<const SCEVConstant *>(DimSize) 1504 ->getAPInt() 1505 .getLimitedValue(); 1506 1507 if (!NewArrayType) 1508 NewArrayType = SAI->getElementType(); 1509 1510 NewArrayType = ArrayType::get(NewArrayType, UnsignedDimSize); 1511 ArraySizeInt *= UnsignedDimSize; 1512 } 1513 1514 if (SAI->isOnHeap()) { 1515 LLVMContext &Ctx = NewArrayType->getContext(); 1516 1517 // Get the IntPtrTy from the Datalayout 1518 auto IntPtrTy = DL.getIntPtrType(Ctx); 1519 1520 // Get the size of the element type in bits 1521 unsigned Size = SAI->getElemSizeInBytes(); 1522 1523 // Insert the malloc call at polly.start 1524 auto InstIt = std::get<0>(StartExitBlocks)->getTerminator(); 1525 auto *CreatedArray = CallInst::CreateMalloc( 1526 &*InstIt, IntPtrTy, SAI->getElementType(), 1527 ConstantInt::get(Type::getInt64Ty(Ctx), Size), 1528 ConstantInt::get(Type::getInt64Ty(Ctx), ArraySizeInt), nullptr, 1529 SAI->getName()); 1530 1531 SAI->setBasePtr(CreatedArray); 1532 1533 // Insert the free call at polly.exiting 1534 CallInst::CreateFree(CreatedArray, 1535 std::get<1>(StartExitBlocks)->getTerminator()); 1536 } else { 1537 auto InstIt = Builder.GetInsertBlock() 1538 ->getParent() 1539 ->getEntryBlock() 1540 .getTerminator(); 1541 1542 auto *CreatedArray = new AllocaInst(NewArrayType, DL.getAllocaAddrSpace(), 1543 SAI->getName(), &*InstIt); 1544 if (PollyTargetFirstLevelCacheLineSize) 1545 CreatedArray->setAlignment(Align(PollyTargetFirstLevelCacheLineSize)); 1546 SAI->setBasePtr(CreatedArray); 1547 } 1548 } 1549 } 1550 1551 bool IslNodeBuilder::preloadInvariantLoads() { 1552 auto &InvariantEquivClasses = S.getInvariantAccesses(); 1553 if (InvariantEquivClasses.empty()) 1554 return true; 1555 1556 BasicBlock *PreLoadBB = SplitBlock(Builder.GetInsertBlock(), 1557 &*Builder.GetInsertPoint(), &DT, &LI); 1558 PreLoadBB->setName("polly.preload.begin"); 1559 Builder.SetInsertPoint(&PreLoadBB->front()); 1560 1561 for (auto &IAClass : InvariantEquivClasses) 1562 if (!preloadInvariantEquivClass(IAClass)) 1563 return false; 1564 1565 return true; 1566 } 1567 1568 void IslNodeBuilder::addParameters(__isl_take isl_set *Context) { 1569 // Materialize values for the parameters of the SCoP. 1570 materializeParameters(); 1571 1572 // materialize the outermost dimension parameters for a Fortran array. 1573 // NOTE: materializeParameters() does not work since it looks through 1574 // the SCEVs. We don't have a corresponding SCEV for the array size 1575 // parameter 1576 materializeFortranArrayOutermostDimension(); 1577 1578 // Generate values for the current loop iteration for all surrounding loops. 1579 // 1580 // We may also reference loops outside of the scop which do not contain the 1581 // scop itself, but as the number of such scops may be arbitrarily large we do 1582 // not generate code for them here, but only at the point of code generation 1583 // where these values are needed. 1584 Loop *L = LI.getLoopFor(S.getEntry()); 1585 1586 while (L != nullptr && S.contains(L)) 1587 L = L->getParentLoop(); 1588 1589 while (L != nullptr) { 1590 materializeNonScopLoopInductionVariable(L); 1591 L = L->getParentLoop(); 1592 } 1593 1594 isl_set_free(Context); 1595 } 1596 1597 Value *IslNodeBuilder::generateSCEV(const SCEV *Expr) { 1598 /// We pass the insert location of our Builder, as Polly ensures during IR 1599 /// generation that there is always a valid CFG into which instructions are 1600 /// inserted. As a result, the insertpoint is known to be always followed by a 1601 /// terminator instruction. This means the insert point may be specified by a 1602 /// terminator instruction, but it can never point to an ->end() iterator 1603 /// which does not have a corresponding instruction. Hence, dereferencing 1604 /// the insertpoint to obtain an instruction is known to be save. 1605 /// 1606 /// We also do not need to update the Builder here, as new instructions are 1607 /// always inserted _before_ the given InsertLocation. As a result, the 1608 /// insert location remains valid. 1609 assert(Builder.GetInsertBlock()->end() != Builder.GetInsertPoint() && 1610 "Insert location points after last valid instruction"); 1611 Instruction *InsertLocation = &*Builder.GetInsertPoint(); 1612 return expandCodeFor(S, SE, DL, "polly", Expr, Expr->getType(), 1613 InsertLocation, &ValueMap, 1614 StartBlock->getSinglePredecessor()); 1615 } 1616 1617 /// The AST expression we generate to perform the run-time check assumes 1618 /// computations on integer types of infinite size. As we only use 64-bit 1619 /// arithmetic we check for overflows, in case of which we set the result 1620 /// of this run-time check to false to be conservatively correct, 1621 Value *IslNodeBuilder::createRTC(isl_ast_expr *Condition) { 1622 auto ExprBuilder = getExprBuilder(); 1623 1624 // In case the AST expression has integers larger than 64 bit, bail out. The 1625 // resulting LLVM-IR will contain operations on types that use more than 64 1626 // bits. These are -- in case wrapping intrinsics are used -- translated to 1627 // runtime library calls that are not available on all systems (e.g., Android) 1628 // and consequently will result in linker errors. 1629 if (ExprBuilder.hasLargeInts(isl::manage_copy(Condition))) { 1630 isl_ast_expr_free(Condition); 1631 return Builder.getFalse(); 1632 } 1633 1634 ExprBuilder.setTrackOverflow(true); 1635 Value *RTC = ExprBuilder.create(Condition); 1636 if (!RTC->getType()->isIntegerTy(1)) 1637 RTC = Builder.CreateIsNotNull(RTC); 1638 Value *OverflowHappened = 1639 Builder.CreateNot(ExprBuilder.getOverflowState(), "polly.rtc.overflown"); 1640 1641 if (PollyGenerateRTCPrint) { 1642 auto *F = Builder.GetInsertBlock()->getParent(); 1643 RuntimeDebugBuilder::createCPUPrinter( 1644 Builder, 1645 "F: " + F->getName().str() + " R: " + S.getRegion().getNameStr() + 1646 "RTC: ", 1647 RTC, " Overflow: ", OverflowHappened, 1648 "\n" 1649 " (0 failed, -1 succeeded)\n" 1650 " (if one or both are 0 falling back to original code, if both are -1 " 1651 "executing Polly code)\n"); 1652 } 1653 1654 RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result"); 1655 ExprBuilder.setTrackOverflow(false); 1656 1657 if (!isa<ConstantInt>(RTC)) 1658 VersionedScops++; 1659 1660 return RTC; 1661 } 1662