1 //===--- BlockGenerators.cpp - Generate code for statements -----*- C++ -*-===// 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 // This file implements the BlockGenerator and VectorBlockGenerator classes, 11 // which generate sequential code and vectorized code for a polyhedral 12 // statement, respectively. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "polly/ScopInfo.h" 17 #include "isl/aff.h" 18 #include "isl/ast.h" 19 #include "isl/ast_build.h" 20 #include "isl/set.h" 21 #include "polly/CodeGen/BlockGenerators.h" 22 #include "polly/CodeGen/CodeGeneration.h" 23 #include "polly/CodeGen/IslExprBuilder.h" 24 #include "polly/Options.h" 25 #include "polly/Support/GICHelper.h" 26 #include "polly/Support/SCEVValidator.h" 27 #include "polly/Support/ScopHelper.h" 28 #include "llvm/Analysis/LoopInfo.h" 29 #include "llvm/Analysis/ScalarEvolution.h" 30 #include "llvm/Analysis/ScalarEvolutionExpander.h" 31 #include "llvm/IR/IntrinsicInst.h" 32 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 33 34 using namespace llvm; 35 using namespace polly; 36 37 static cl::opt<bool> Aligned("enable-polly-aligned", 38 cl::desc("Assumed aligned memory accesses."), 39 cl::Hidden, cl::init(false), cl::ZeroOrMore, 40 cl::cat(PollyCategory)); 41 42 bool polly::canSynthesize(const Instruction *I, const llvm::LoopInfo *LI, 43 ScalarEvolution *SE, const Region *R) { 44 if (!I || !SE->isSCEVable(I->getType())) 45 return false; 46 47 if (const SCEV *Scev = SE->getSCEV(const_cast<Instruction *>(I))) 48 if (!isa<SCEVCouldNotCompute>(Scev)) 49 if (!hasScalarDepsInsideRegion(Scev, R)) 50 return true; 51 52 return false; 53 } 54 55 BlockGenerator::BlockGenerator(PollyIRBuilder &B, ScopStmt &Stmt, Pass *P, 56 LoopInfo &LI, ScalarEvolution &SE, 57 isl_ast_build *Build, 58 IslExprBuilder *ExprBuilder) 59 : Builder(B), Statement(Stmt), P(P), LI(LI), SE(SE), Build(Build), 60 ExprBuilder(ExprBuilder) {} 61 62 Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap, 63 ValueMapT &GlobalMap, LoopToScevMapT <S, 64 Loop *L) const { 65 // We assume constants never change. 66 // This avoids map lookups for many calls to this function. 67 if (isa<Constant>(Old)) 68 return const_cast<Value *>(Old); 69 70 if (Value *New = GlobalMap.lookup(Old)) { 71 if (Old->getType()->getScalarSizeInBits() < 72 New->getType()->getScalarSizeInBits()) 73 New = Builder.CreateTruncOrBitCast(New, Old->getType()); 74 75 return New; 76 } 77 78 if (Value *New = BBMap.lookup(Old)) 79 return New; 80 81 if (SE.isSCEVable(Old->getType())) 82 if (const SCEV *Scev = SE.getSCEVAtScope(const_cast<Value *>(Old), L)) { 83 if (!isa<SCEVCouldNotCompute>(Scev)) { 84 const SCEV *NewScev = apply(Scev, LTS, SE); 85 ValueToValueMap VTV; 86 VTV.insert(BBMap.begin(), BBMap.end()); 87 VTV.insert(GlobalMap.begin(), GlobalMap.end()); 88 NewScev = SCEVParameterRewriter::rewrite(NewScev, SE, VTV); 89 SCEVExpander Expander(SE, "polly"); 90 Value *Expanded = Expander.expandCodeFor(NewScev, Old->getType(), 91 Builder.GetInsertPoint()); 92 93 BBMap[Old] = Expanded; 94 return Expanded; 95 } 96 } 97 98 // A scop-constant value defined by a global or a function parameter. 99 if (isa<GlobalValue>(Old) || isa<Argument>(Old)) 100 return const_cast<Value *>(Old); 101 102 // A scop-constant value defined by an instruction executed outside the scop. 103 if (const Instruction *Inst = dyn_cast<Instruction>(Old)) 104 if (!Statement.getParent()->getRegion().contains(Inst->getParent())) 105 return const_cast<Value *>(Old); 106 107 // The scalar dependence is neither available nor SCEVCodegenable. 108 llvm_unreachable("Unexpected scalar dependence in region!"); 109 return nullptr; 110 } 111 112 void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap, 113 ValueMapT &GlobalMap, LoopToScevMapT <S) { 114 // We do not generate debug intrinsics as we did not investigate how to 115 // copy them correctly. At the current state, they just crash the code 116 // generation as the meta-data operands are not correctly copied. 117 if (isa<DbgInfoIntrinsic>(Inst)) 118 return; 119 120 Instruction *NewInst = Inst->clone(); 121 122 // Replace old operands with the new ones. 123 for (Value *OldOperand : Inst->operands()) { 124 Value *NewOperand = 125 getNewValue(OldOperand, BBMap, GlobalMap, LTS, getLoopForInst(Inst)); 126 127 if (!NewOperand) { 128 assert(!isa<StoreInst>(NewInst) && 129 "Store instructions are always needed!"); 130 delete NewInst; 131 return; 132 } 133 134 NewInst->replaceUsesOfWith(OldOperand, NewOperand); 135 } 136 137 Builder.Insert(NewInst); 138 BBMap[Inst] = NewInst; 139 140 if (!NewInst->getType()->isVoidTy()) 141 NewInst->setName("p_" + Inst->getName()); 142 } 143 144 Value *BlockGenerator::getNewAccessOperand(const MemoryAccess &MA) { 145 isl_pw_multi_aff *PWAccRel; 146 isl_union_map *Schedule; 147 isl_ast_expr *Expr; 148 149 assert(ExprBuilder && Build && 150 "Cannot generate new value without IslExprBuilder!"); 151 152 Schedule = isl_ast_build_get_schedule(Build); 153 PWAccRel = MA.applyScheduleToAccessRelation(Schedule); 154 155 Expr = isl_ast_build_access_from_pw_multi_aff(Build, PWAccRel); 156 Expr = isl_ast_expr_address_of(Expr); 157 158 return ExprBuilder->create(Expr); 159 } 160 161 Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst, 162 const Value *Pointer, 163 ValueMapT &BBMap, 164 ValueMapT &GlobalMap, 165 LoopToScevMapT <S) { 166 const MemoryAccess &MA = Statement.getAccessFor(Inst); 167 168 Value *NewPointer; 169 if (MA.hasNewAccessRelation()) 170 NewPointer = getNewAccessOperand(MA); 171 else 172 NewPointer = 173 getNewValue(Pointer, BBMap, GlobalMap, LTS, getLoopForInst(Inst)); 174 175 return NewPointer; 176 } 177 178 Loop *BlockGenerator::getLoopForInst(const llvm::Instruction *Inst) { 179 return LI.getLoopFor(Inst->getParent()); 180 } 181 182 Value *BlockGenerator::generateScalarLoad(const LoadInst *Load, 183 ValueMapT &BBMap, 184 ValueMapT &GlobalMap, 185 LoopToScevMapT <S) { 186 const Value *Pointer = Load->getPointerOperand(); 187 Value *NewPointer = 188 generateLocationAccessed(Load, Pointer, BBMap, GlobalMap, LTS); 189 Value *ScalarLoad = Builder.CreateAlignedLoad( 190 NewPointer, Load->getAlignment(), Load->getName() + "_p_scalar_"); 191 return ScalarLoad; 192 } 193 194 Value *BlockGenerator::generateScalarStore(const StoreInst *Store, 195 ValueMapT &BBMap, 196 ValueMapT &GlobalMap, 197 LoopToScevMapT <S) { 198 const Value *Pointer = Store->getPointerOperand(); 199 Value *NewPointer = 200 generateLocationAccessed(Store, Pointer, BBMap, GlobalMap, LTS); 201 Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap, 202 LTS, getLoopForInst(Store)); 203 204 Value *NewStore = Builder.CreateAlignedStore(ValueOperand, NewPointer, 205 Store->getAlignment()); 206 return NewStore; 207 } 208 209 void BlockGenerator::copyInstruction(const Instruction *Inst, ValueMapT &BBMap, 210 ValueMapT &GlobalMap, 211 LoopToScevMapT <S) { 212 // Terminator instructions control the control flow. They are explicitly 213 // expressed in the clast and do not need to be copied. 214 if (Inst->isTerminator()) 215 return; 216 217 if (canSynthesize(Inst, &P->getAnalysis<LoopInfo>(), &SE, 218 &Statement.getParent()->getRegion())) 219 return; 220 221 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) { 222 Value *NewLoad = generateScalarLoad(Load, BBMap, GlobalMap, LTS); 223 // Compute NewLoad before its insertion in BBMap to make the insertion 224 // deterministic. 225 BBMap[Load] = NewLoad; 226 return; 227 } 228 229 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) { 230 Value *NewStore = generateScalarStore(Store, BBMap, GlobalMap, LTS); 231 // Compute NewStore before its insertion in BBMap to make the insertion 232 // deterministic. 233 BBMap[Store] = NewStore; 234 return; 235 } 236 237 copyInstScalar(Inst, BBMap, GlobalMap, LTS); 238 } 239 240 void BlockGenerator::copyBB(ValueMapT &GlobalMap, LoopToScevMapT <S) { 241 BasicBlock *BB = Statement.getBasicBlock(); 242 BasicBlock *CopyBB = 243 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P); 244 CopyBB->setName("polly.stmt." + BB->getName()); 245 Builder.SetInsertPoint(CopyBB->begin()); 246 247 ValueMapT BBMap; 248 249 for (Instruction &Inst : *BB) 250 copyInstruction(&Inst, BBMap, GlobalMap, LTS); 251 } 252 253 VectorBlockGenerator::VectorBlockGenerator( 254 PollyIRBuilder &B, VectorValueMapT &GlobalMaps, 255 std::vector<LoopToScevMapT> &VLTS, ScopStmt &Stmt, 256 __isl_keep isl_map *Schedule, Pass *P, LoopInfo &LI, ScalarEvolution &SE, 257 __isl_keep isl_ast_build *Build, IslExprBuilder *ExprBuilder) 258 : BlockGenerator(B, Stmt, P, LI, SE, Build, ExprBuilder), 259 GlobalMaps(GlobalMaps), VLTS(VLTS), Schedule(Schedule) { 260 assert(GlobalMaps.size() > 1 && "Only one vector lane found"); 261 assert(Schedule && "No statement domain provided"); 262 } 263 264 Value *VectorBlockGenerator::getVectorValue(const Value *Old, 265 ValueMapT &VectorMap, 266 VectorValueMapT &ScalarMaps, 267 Loop *L) { 268 if (Value *NewValue = VectorMap.lookup(Old)) 269 return NewValue; 270 271 int Width = getVectorWidth(); 272 273 Value *Vector = UndefValue::get(VectorType::get(Old->getType(), Width)); 274 275 for (int Lane = 0; Lane < Width; Lane++) 276 Vector = Builder.CreateInsertElement( 277 Vector, 278 getNewValue(Old, ScalarMaps[Lane], GlobalMaps[Lane], VLTS[Lane], L), 279 Builder.getInt32(Lane)); 280 281 VectorMap[Old] = Vector; 282 283 return Vector; 284 } 285 286 Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) { 287 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType()); 288 assert(PointerTy && "PointerType expected"); 289 290 Type *ScalarType = PointerTy->getElementType(); 291 VectorType *VectorType = VectorType::get(ScalarType, Width); 292 293 return PointerType::getUnqual(VectorType); 294 } 295 296 Value * 297 VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load, 298 VectorValueMapT &ScalarMaps, 299 bool NegativeStride = false) { 300 unsigned VectorWidth = getVectorWidth(); 301 const Value *Pointer = Load->getPointerOperand(); 302 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth); 303 unsigned Offset = NegativeStride ? VectorWidth - 1 : 0; 304 305 Value *NewPointer = nullptr; 306 NewPointer = generateLocationAccessed(Load, Pointer, ScalarMaps[Offset], 307 GlobalMaps[Offset], VLTS[Offset]); 308 Value *VectorPtr = 309 Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr"); 310 LoadInst *VecLoad = 311 Builder.CreateLoad(VectorPtr, Load->getName() + "_p_vec_full"); 312 if (!Aligned) 313 VecLoad->setAlignment(8); 314 315 if (NegativeStride) { 316 SmallVector<Constant *, 16> Indices; 317 for (int i = VectorWidth - 1; i >= 0; i--) 318 Indices.push_back(ConstantInt::get(Builder.getInt32Ty(), i)); 319 Constant *SV = llvm::ConstantVector::get(Indices); 320 Value *RevVecLoad = Builder.CreateShuffleVector( 321 VecLoad, VecLoad, SV, Load->getName() + "_reverse"); 322 return RevVecLoad; 323 } 324 325 return VecLoad; 326 } 327 328 Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load, 329 ValueMapT &BBMap) { 330 const Value *Pointer = Load->getPointerOperand(); 331 Type *VectorPtrType = getVectorPtrTy(Pointer, 1); 332 Value *NewPointer = 333 generateLocationAccessed(Load, Pointer, BBMap, GlobalMaps[0], VLTS[0]); 334 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, 335 Load->getName() + "_p_vec_p"); 336 LoadInst *ScalarLoad = 337 Builder.CreateLoad(VectorPtr, Load->getName() + "_p_splat_one"); 338 339 if (!Aligned) 340 ScalarLoad->setAlignment(8); 341 342 Constant *SplatVector = Constant::getNullValue( 343 VectorType::get(Builder.getInt32Ty(), getVectorWidth())); 344 345 Value *VectorLoad = Builder.CreateShuffleVector( 346 ScalarLoad, ScalarLoad, SplatVector, Load->getName() + "_p_splat"); 347 return VectorLoad; 348 } 349 350 Value * 351 VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load, 352 VectorValueMapT &ScalarMaps) { 353 int VectorWidth = getVectorWidth(); 354 const Value *Pointer = Load->getPointerOperand(); 355 VectorType *VectorType = VectorType::get( 356 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth); 357 358 Value *Vector = UndefValue::get(VectorType); 359 360 for (int i = 0; i < VectorWidth; i++) { 361 Value *NewPointer = generateLocationAccessed(Load, Pointer, ScalarMaps[i], 362 GlobalMaps[i], VLTS[i]); 363 Value *ScalarLoad = 364 Builder.CreateLoad(NewPointer, Load->getName() + "_p_scalar_"); 365 Vector = Builder.CreateInsertElement( 366 Vector, ScalarLoad, Builder.getInt32(i), Load->getName() + "_p_vec_"); 367 } 368 369 return Vector; 370 } 371 372 void VectorBlockGenerator::generateLoad(const LoadInst *Load, 373 ValueMapT &VectorMap, 374 VectorValueMapT &ScalarMaps) { 375 if (PollyVectorizerChoice >= VECTORIZER_FIRST_NEED_GROUPED_UNROLL || 376 !VectorType::isValidElementType(Load->getType())) { 377 for (int i = 0; i < getVectorWidth(); i++) 378 ScalarMaps[i][Load] = 379 generateScalarLoad(Load, ScalarMaps[i], GlobalMaps[i], VLTS[i]); 380 return; 381 } 382 383 const MemoryAccess &Access = Statement.getAccessFor(Load); 384 385 // Make sure we have scalar values available to access the pointer to 386 // the data location. 387 extractScalarValues(Load, VectorMap, ScalarMaps); 388 389 Value *NewLoad; 390 if (Access.isStrideZero(isl_map_copy(Schedule))) 391 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]); 392 else if (Access.isStrideOne(isl_map_copy(Schedule))) 393 NewLoad = generateStrideOneLoad(Load, ScalarMaps); 394 else if (Access.isStrideX(isl_map_copy(Schedule), -1)) 395 NewLoad = generateStrideOneLoad(Load, ScalarMaps, true); 396 else 397 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps); 398 399 VectorMap[Load] = NewLoad; 400 } 401 402 void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst, 403 ValueMapT &VectorMap, 404 VectorValueMapT &ScalarMaps) { 405 int VectorWidth = getVectorWidth(); 406 Value *NewOperand = getVectorValue(Inst->getOperand(0), VectorMap, ScalarMaps, 407 getLoopForInst(Inst)); 408 409 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction"); 410 411 const CastInst *Cast = dyn_cast<CastInst>(Inst); 412 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth); 413 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType); 414 } 415 416 void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst, 417 ValueMapT &VectorMap, 418 VectorValueMapT &ScalarMaps) { 419 Loop *L = getLoopForInst(Inst); 420 Value *OpZero = Inst->getOperand(0); 421 Value *OpOne = Inst->getOperand(1); 422 423 Value *NewOpZero, *NewOpOne; 424 NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps, L); 425 NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps, L); 426 427 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero, NewOpOne, 428 Inst->getName() + "p_vec"); 429 VectorMap[Inst] = NewInst; 430 } 431 432 void VectorBlockGenerator::copyStore(const StoreInst *Store, 433 ValueMapT &VectorMap, 434 VectorValueMapT &ScalarMaps) { 435 const MemoryAccess &Access = Statement.getAccessFor(Store); 436 437 const Value *Pointer = Store->getPointerOperand(); 438 Value *Vector = getVectorValue(Store->getValueOperand(), VectorMap, 439 ScalarMaps, getLoopForInst(Store)); 440 441 // Make sure we have scalar values available to access the pointer to 442 // the data location. 443 extractScalarValues(Store, VectorMap, ScalarMaps); 444 445 if (Access.isStrideOne(isl_map_copy(Schedule))) { 446 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth()); 447 Value *NewPointer = generateLocationAccessed(Store, Pointer, ScalarMaps[0], 448 GlobalMaps[0], VLTS[0]); 449 450 Value *VectorPtr = 451 Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr"); 452 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr); 453 454 if (!Aligned) 455 Store->setAlignment(8); 456 } else { 457 for (unsigned i = 0; i < ScalarMaps.size(); i++) { 458 Value *Scalar = Builder.CreateExtractElement(Vector, Builder.getInt32(i)); 459 Value *NewPointer = generateLocationAccessed( 460 Store, Pointer, ScalarMaps[i], GlobalMaps[i], VLTS[i]); 461 Builder.CreateStore(Scalar, NewPointer); 462 } 463 } 464 } 465 466 bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst, 467 ValueMapT &VectorMap) { 468 for (Value *Operand : Inst->operands()) 469 if (VectorMap.count(Operand)) 470 return true; 471 return false; 472 } 473 474 bool VectorBlockGenerator::extractScalarValues(const Instruction *Inst, 475 ValueMapT &VectorMap, 476 VectorValueMapT &ScalarMaps) { 477 bool HasVectorOperand = false; 478 int VectorWidth = getVectorWidth(); 479 480 for (Value *Operand : Inst->operands()) { 481 ValueMapT::iterator VecOp = VectorMap.find(Operand); 482 483 if (VecOp == VectorMap.end()) 484 continue; 485 486 HasVectorOperand = true; 487 Value *NewVector = VecOp->second; 488 489 for (int i = 0; i < VectorWidth; ++i) { 490 ValueMapT &SM = ScalarMaps[i]; 491 492 // If there is one scalar extracted, all scalar elements should have 493 // already been extracted by the code here. So no need to check for the 494 // existance of all of them. 495 if (SM.count(Operand)) 496 break; 497 498 SM[Operand] = 499 Builder.CreateExtractElement(NewVector, Builder.getInt32(i)); 500 } 501 } 502 503 return HasVectorOperand; 504 } 505 506 void VectorBlockGenerator::copyInstScalarized(const Instruction *Inst, 507 ValueMapT &VectorMap, 508 VectorValueMapT &ScalarMaps) { 509 bool HasVectorOperand; 510 int VectorWidth = getVectorWidth(); 511 512 HasVectorOperand = extractScalarValues(Inst, VectorMap, ScalarMaps); 513 514 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++) 515 BlockGenerator::copyInstruction(Inst, ScalarMaps[VectorLane], 516 GlobalMaps[VectorLane], VLTS[VectorLane]); 517 518 if (!VectorType::isValidElementType(Inst->getType()) || !HasVectorOperand) 519 return; 520 521 // Make the result available as vector value. 522 VectorType *VectorType = VectorType::get(Inst->getType(), VectorWidth); 523 Value *Vector = UndefValue::get(VectorType); 524 525 for (int i = 0; i < VectorWidth; i++) 526 Vector = Builder.CreateInsertElement(Vector, ScalarMaps[i][Inst], 527 Builder.getInt32(i)); 528 529 VectorMap[Inst] = Vector; 530 } 531 532 int VectorBlockGenerator::getVectorWidth() { return GlobalMaps.size(); } 533 534 void VectorBlockGenerator::copyInstruction(const Instruction *Inst, 535 ValueMapT &VectorMap, 536 VectorValueMapT &ScalarMaps) { 537 // Terminator instructions control the control flow. They are explicitly 538 // expressed in the clast and do not need to be copied. 539 if (Inst->isTerminator()) 540 return; 541 542 if (canSynthesize(Inst, &P->getAnalysis<LoopInfo>(), &SE, 543 &Statement.getParent()->getRegion())) 544 return; 545 546 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) { 547 generateLoad(Load, VectorMap, ScalarMaps); 548 return; 549 } 550 551 if (hasVectorOperands(Inst, VectorMap)) { 552 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) { 553 copyStore(Store, VectorMap, ScalarMaps); 554 return; 555 } 556 557 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) { 558 copyUnaryInst(Unary, VectorMap, ScalarMaps); 559 return; 560 } 561 562 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) { 563 copyBinaryInst(Binary, VectorMap, ScalarMaps); 564 return; 565 } 566 567 // Falltrough: We generate scalar instructions, if we don't know how to 568 // generate vector code. 569 } 570 571 copyInstScalarized(Inst, VectorMap, ScalarMaps); 572 } 573 574 void VectorBlockGenerator::copyBB() { 575 BasicBlock *BB = Statement.getBasicBlock(); 576 BasicBlock *CopyBB = 577 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P); 578 CopyBB->setName("polly.stmt." + BB->getName()); 579 Builder.SetInsertPoint(CopyBB->begin()); 580 581 // Create two maps that store the mapping from the original instructions of 582 // the old basic block to their copies in the new basic block. Those maps 583 // are basic block local. 584 // 585 // As vector code generation is supported there is one map for scalar values 586 // and one for vector values. 587 // 588 // In case we just do scalar code generation, the vectorMap is not used and 589 // the scalarMap has just one dimension, which contains the mapping. 590 // 591 // In case vector code generation is done, an instruction may either appear 592 // in the vector map once (as it is calculating >vectorwidth< values at a 593 // time. Or (if the values are calculated using scalar operations), it 594 // appears once in every dimension of the scalarMap. 595 VectorValueMapT ScalarBlockMap(getVectorWidth()); 596 ValueMapT VectorBlockMap; 597 598 for (Instruction &Inst : *BB) 599 copyInstruction(&Inst, VectorBlockMap, ScalarBlockMap); 600 } 601