1 //===- Scalarizer.cpp - Scalarize vector operations -----------------------===// 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 pass converts vector operations into scalar operations, in order 10 // to expose optimization opportunities on the individual scalar operations. 11 // It is mainly intended for targets that do not have vector units, but it 12 // may also be useful for revectorizing code to different vector widths. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/Transforms/Scalar/Scalarizer.h" 17 #include "llvm/ADT/PostOrderIterator.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/Analysis/VectorUtils.h" 21 #include "llvm/IR/Argument.h" 22 #include "llvm/IR/BasicBlock.h" 23 #include "llvm/IR/Constants.h" 24 #include "llvm/IR/DataLayout.h" 25 #include "llvm/IR/DerivedTypes.h" 26 #include "llvm/IR/Dominators.h" 27 #include "llvm/IR/Function.h" 28 #include "llvm/IR/IRBuilder.h" 29 #include "llvm/IR/InstVisitor.h" 30 #include "llvm/IR/InstrTypes.h" 31 #include "llvm/IR/Instruction.h" 32 #include "llvm/IR/Instructions.h" 33 #include "llvm/IR/Intrinsics.h" 34 #include "llvm/IR/LLVMContext.h" 35 #include "llvm/IR/Module.h" 36 #include "llvm/IR/Type.h" 37 #include "llvm/IR/Value.h" 38 #include "llvm/InitializePasses.h" 39 #include "llvm/Pass.h" 40 #include "llvm/Support/Casting.h" 41 #include "llvm/Support/CommandLine.h" 42 #include "llvm/Transforms/Utils/Local.h" 43 #include <cassert> 44 #include <cstdint> 45 #include <iterator> 46 #include <map> 47 #include <utility> 48 49 using namespace llvm; 50 51 #define DEBUG_TYPE "scalarizer" 52 53 static cl::opt<bool> ScalarizeVariableInsertExtract( 54 "scalarize-variable-insert-extract", cl::init(true), cl::Hidden, 55 cl::desc("Allow the scalarizer pass to scalarize " 56 "insertelement/extractelement with variable index")); 57 58 // This is disabled by default because having separate loads and stores 59 // makes it more likely that the -combiner-alias-analysis limits will be 60 // reached. 61 static cl::opt<bool> 62 ScalarizeLoadStore("scalarize-load-store", cl::init(false), cl::Hidden, 63 cl::desc("Allow the scalarizer pass to scalarize loads and store")); 64 65 namespace { 66 67 BasicBlock::iterator skipPastPhiNodesAndDbg(BasicBlock::iterator Itr) { 68 BasicBlock *BB = Itr->getParent(); 69 if (isa<PHINode>(Itr)) 70 Itr = BB->getFirstInsertionPt(); 71 if (Itr != BB->end()) 72 Itr = skipDebugIntrinsics(Itr); 73 return Itr; 74 } 75 76 // Used to store the scattered form of a vector. 77 using ValueVector = SmallVector<Value *, 8>; 78 79 // Used to map a vector Value to its scattered form. We use std::map 80 // because we want iterators to persist across insertion and because the 81 // values are relatively large. 82 using ScatterMap = std::map<Value *, ValueVector>; 83 84 // Lists Instructions that have been replaced with scalar implementations, 85 // along with a pointer to their scattered forms. 86 using GatherList = SmallVector<std::pair<Instruction *, ValueVector *>, 16>; 87 88 // Provides a very limited vector-like interface for lazily accessing one 89 // component of a scattered vector or vector pointer. 90 class Scatterer { 91 public: 92 Scatterer() = default; 93 94 // Scatter V into Size components. If new instructions are needed, 95 // insert them before BBI in BB. If Cache is nonnull, use it to cache 96 // the results. 97 Scatterer(BasicBlock *bb, BasicBlock::iterator bbi, Value *v, Type *PtrElemTy, 98 ValueVector *cachePtr = nullptr); 99 100 // Return component I, creating a new Value for it if necessary. 101 Value *operator[](unsigned I); 102 103 // Return the number of components. 104 unsigned size() const { return Size; } 105 106 private: 107 BasicBlock *BB; 108 BasicBlock::iterator BBI; 109 Value *V; 110 Type *PtrElemTy; 111 ValueVector *CachePtr; 112 ValueVector Tmp; 113 unsigned Size; 114 }; 115 116 // FCmpSpliiter(FCI)(Builder, X, Y, Name) uses Builder to create an FCmp 117 // called Name that compares X and Y in the same way as FCI. 118 struct FCmpSplitter { 119 FCmpSplitter(FCmpInst &fci) : FCI(fci) {} 120 121 Value *operator()(IRBuilder<> &Builder, Value *Op0, Value *Op1, 122 const Twine &Name) const { 123 return Builder.CreateFCmp(FCI.getPredicate(), Op0, Op1, Name); 124 } 125 126 FCmpInst &FCI; 127 }; 128 129 // ICmpSpliiter(ICI)(Builder, X, Y, Name) uses Builder to create an ICmp 130 // called Name that compares X and Y in the same way as ICI. 131 struct ICmpSplitter { 132 ICmpSplitter(ICmpInst &ici) : ICI(ici) {} 133 134 Value *operator()(IRBuilder<> &Builder, Value *Op0, Value *Op1, 135 const Twine &Name) const { 136 return Builder.CreateICmp(ICI.getPredicate(), Op0, Op1, Name); 137 } 138 139 ICmpInst &ICI; 140 }; 141 142 // UnarySpliiter(UO)(Builder, X, Name) uses Builder to create 143 // a unary operator like UO called Name with operand X. 144 struct UnarySplitter { 145 UnarySplitter(UnaryOperator &uo) : UO(uo) {} 146 147 Value *operator()(IRBuilder<> &Builder, Value *Op, const Twine &Name) const { 148 return Builder.CreateUnOp(UO.getOpcode(), Op, Name); 149 } 150 151 UnaryOperator &UO; 152 }; 153 154 // BinarySpliiter(BO)(Builder, X, Y, Name) uses Builder to create 155 // a binary operator like BO called Name with operands X and Y. 156 struct BinarySplitter { 157 BinarySplitter(BinaryOperator &bo) : BO(bo) {} 158 159 Value *operator()(IRBuilder<> &Builder, Value *Op0, Value *Op1, 160 const Twine &Name) const { 161 return Builder.CreateBinOp(BO.getOpcode(), Op0, Op1, Name); 162 } 163 164 BinaryOperator &BO; 165 }; 166 167 // Information about a load or store that we're scalarizing. 168 struct VectorLayout { 169 VectorLayout() = default; 170 171 // Return the alignment of element I. 172 Align getElemAlign(unsigned I) { 173 return commonAlignment(VecAlign, I * ElemSize); 174 } 175 176 // The type of the vector. 177 VectorType *VecTy = nullptr; 178 179 // The type of each element. 180 Type *ElemTy = nullptr; 181 182 // The alignment of the vector. 183 Align VecAlign; 184 185 // The size of each element. 186 uint64_t ElemSize = 0; 187 }; 188 189 class ScalarizerVisitor : public InstVisitor<ScalarizerVisitor, bool> { 190 public: 191 ScalarizerVisitor(unsigned ParallelLoopAccessMDKind, DominatorTree *DT) 192 : ParallelLoopAccessMDKind(ParallelLoopAccessMDKind), DT(DT) { 193 } 194 195 bool visit(Function &F); 196 197 // InstVisitor methods. They return true if the instruction was scalarized, 198 // false if nothing changed. 199 bool visitInstruction(Instruction &I) { return false; } 200 bool visitSelectInst(SelectInst &SI); 201 bool visitICmpInst(ICmpInst &ICI); 202 bool visitFCmpInst(FCmpInst &FCI); 203 bool visitUnaryOperator(UnaryOperator &UO); 204 bool visitBinaryOperator(BinaryOperator &BO); 205 bool visitGetElementPtrInst(GetElementPtrInst &GEPI); 206 bool visitCastInst(CastInst &CI); 207 bool visitBitCastInst(BitCastInst &BCI); 208 bool visitInsertElementInst(InsertElementInst &IEI); 209 bool visitExtractElementInst(ExtractElementInst &EEI); 210 bool visitShuffleVectorInst(ShuffleVectorInst &SVI); 211 bool visitPHINode(PHINode &PHI); 212 bool visitLoadInst(LoadInst &LI); 213 bool visitStoreInst(StoreInst &SI); 214 bool visitCallInst(CallInst &ICI); 215 216 private: 217 Scatterer scatter(Instruction *Point, Value *V, Type *PtrElemTy = nullptr); 218 void gather(Instruction *Op, const ValueVector &CV); 219 bool canTransferMetadata(unsigned Kind); 220 void transferMetadataAndIRFlags(Instruction *Op, const ValueVector &CV); 221 Optional<VectorLayout> getVectorLayout(Type *Ty, Align Alignment, 222 const DataLayout &DL); 223 bool finish(); 224 225 template<typename T> bool splitUnary(Instruction &, const T &); 226 template<typename T> bool splitBinary(Instruction &, const T &); 227 228 bool splitCall(CallInst &CI); 229 230 ScatterMap Scattered; 231 GatherList Gathered; 232 233 SmallVector<WeakTrackingVH, 32> PotentiallyDeadInstrs; 234 235 unsigned ParallelLoopAccessMDKind; 236 237 DominatorTree *DT; 238 }; 239 240 class ScalarizerLegacyPass : public FunctionPass { 241 public: 242 static char ID; 243 244 ScalarizerLegacyPass() : FunctionPass(ID) { 245 initializeScalarizerLegacyPassPass(*PassRegistry::getPassRegistry()); 246 } 247 248 bool runOnFunction(Function &F) override; 249 250 void getAnalysisUsage(AnalysisUsage& AU) const override { 251 AU.addRequired<DominatorTreeWrapperPass>(); 252 AU.addPreserved<DominatorTreeWrapperPass>(); 253 } 254 }; 255 256 } // end anonymous namespace 257 258 char ScalarizerLegacyPass::ID = 0; 259 INITIALIZE_PASS_BEGIN(ScalarizerLegacyPass, "scalarizer", 260 "Scalarize vector operations", false, false) 261 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 262 INITIALIZE_PASS_END(ScalarizerLegacyPass, "scalarizer", 263 "Scalarize vector operations", false, false) 264 265 Scatterer::Scatterer(BasicBlock *bb, BasicBlock::iterator bbi, Value *v, 266 Type *PtrElemTy, ValueVector *cachePtr) 267 : BB(bb), BBI(bbi), V(v), PtrElemTy(PtrElemTy), CachePtr(cachePtr) { 268 Type *Ty = V->getType(); 269 if (Ty->isPointerTy()) { 270 assert(cast<PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(PtrElemTy) && 271 "Pointer element type mismatch"); 272 Ty = PtrElemTy; 273 } 274 Size = cast<FixedVectorType>(Ty)->getNumElements(); 275 if (!CachePtr) 276 Tmp.resize(Size, nullptr); 277 else if (CachePtr->empty()) 278 CachePtr->resize(Size, nullptr); 279 else 280 assert(Size == CachePtr->size() && "Inconsistent vector sizes"); 281 } 282 283 // Return component I, creating a new Value for it if necessary. 284 Value *Scatterer::operator[](unsigned I) { 285 ValueVector &CV = (CachePtr ? *CachePtr : Tmp); 286 // Try to reuse a previous value. 287 if (CV[I]) 288 return CV[I]; 289 IRBuilder<> Builder(BB, BBI); 290 if (PtrElemTy) { 291 Type *VectorElemTy = cast<VectorType>(PtrElemTy)->getElementType(); 292 if (!CV[0]) { 293 Type *NewPtrTy = PointerType::get( 294 VectorElemTy, V->getType()->getPointerAddressSpace()); 295 CV[0] = Builder.CreateBitCast(V, NewPtrTy, V->getName() + ".i0"); 296 } 297 if (I != 0) 298 CV[I] = Builder.CreateConstGEP1_32(VectorElemTy, CV[0], I, 299 V->getName() + ".i" + Twine(I)); 300 } else { 301 // Search through a chain of InsertElementInsts looking for element I. 302 // Record other elements in the cache. The new V is still suitable 303 // for all uncached indices. 304 while (true) { 305 InsertElementInst *Insert = dyn_cast<InsertElementInst>(V); 306 if (!Insert) 307 break; 308 ConstantInt *Idx = dyn_cast<ConstantInt>(Insert->getOperand(2)); 309 if (!Idx) 310 break; 311 unsigned J = Idx->getZExtValue(); 312 V = Insert->getOperand(0); 313 if (I == J) { 314 CV[J] = Insert->getOperand(1); 315 return CV[J]; 316 } else if (!CV[J]) { 317 // Only cache the first entry we find for each index we're not actively 318 // searching for. This prevents us from going too far up the chain and 319 // caching incorrect entries. 320 CV[J] = Insert->getOperand(1); 321 } 322 } 323 CV[I] = Builder.CreateExtractElement(V, Builder.getInt32(I), 324 V->getName() + ".i" + Twine(I)); 325 } 326 return CV[I]; 327 } 328 329 bool ScalarizerLegacyPass::runOnFunction(Function &F) { 330 if (skipFunction(F)) 331 return false; 332 333 Module &M = *F.getParent(); 334 unsigned ParallelLoopAccessMDKind = 335 M.getContext().getMDKindID("llvm.mem.parallel_loop_access"); 336 DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 337 ScalarizerVisitor Impl(ParallelLoopAccessMDKind, DT); 338 return Impl.visit(F); 339 } 340 341 FunctionPass *llvm::createScalarizerPass() { 342 return new ScalarizerLegacyPass(); 343 } 344 345 bool ScalarizerVisitor::visit(Function &F) { 346 assert(Gathered.empty() && Scattered.empty()); 347 348 // To ensure we replace gathered components correctly we need to do an ordered 349 // traversal of the basic blocks in the function. 350 ReversePostOrderTraversal<BasicBlock *> RPOT(&F.getEntryBlock()); 351 for (BasicBlock *BB : RPOT) { 352 for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE;) { 353 Instruction *I = &*II; 354 bool Done = InstVisitor::visit(I); 355 ++II; 356 if (Done && I->getType()->isVoidTy()) 357 I->eraseFromParent(); 358 } 359 } 360 return finish(); 361 } 362 363 // Return a scattered form of V that can be accessed by Point. V must be a 364 // vector or a pointer to a vector. 365 Scatterer ScalarizerVisitor::scatter(Instruction *Point, Value *V, 366 Type *PtrElemTy) { 367 if (Argument *VArg = dyn_cast<Argument>(V)) { 368 // Put the scattered form of arguments in the entry block, 369 // so that it can be used everywhere. 370 Function *F = VArg->getParent(); 371 BasicBlock *BB = &F->getEntryBlock(); 372 return Scatterer(BB, BB->begin(), V, PtrElemTy, &Scattered[V]); 373 } 374 if (Instruction *VOp = dyn_cast<Instruction>(V)) { 375 // When scalarizing PHI nodes we might try to examine/rewrite InsertElement 376 // nodes in predecessors. If those predecessors are unreachable from entry, 377 // then the IR in those blocks could have unexpected properties resulting in 378 // infinite loops in Scatterer::operator[]. By simply treating values 379 // originating from instructions in unreachable blocks as undef we do not 380 // need to analyse them further. 381 if (!DT->isReachableFromEntry(VOp->getParent())) 382 return Scatterer(Point->getParent(), Point->getIterator(), 383 UndefValue::get(V->getType()), PtrElemTy); 384 // Put the scattered form of an instruction directly after the 385 // instruction, skipping over PHI nodes and debug intrinsics. 386 BasicBlock *BB = VOp->getParent(); 387 return Scatterer( 388 BB, skipPastPhiNodesAndDbg(std::next(BasicBlock::iterator(VOp))), V, 389 PtrElemTy, &Scattered[V]); 390 } 391 // In the fallback case, just put the scattered before Point and 392 // keep the result local to Point. 393 return Scatterer(Point->getParent(), Point->getIterator(), V, PtrElemTy); 394 } 395 396 // Replace Op with the gathered form of the components in CV. Defer the 397 // deletion of Op and creation of the gathered form to the end of the pass, 398 // so that we can avoid creating the gathered form if all uses of Op are 399 // replaced with uses of CV. 400 void ScalarizerVisitor::gather(Instruction *Op, const ValueVector &CV) { 401 transferMetadataAndIRFlags(Op, CV); 402 403 // If we already have a scattered form of Op (created from ExtractElements 404 // of Op itself), replace them with the new form. 405 ValueVector &SV = Scattered[Op]; 406 if (!SV.empty()) { 407 for (unsigned I = 0, E = SV.size(); I != E; ++I) { 408 Value *V = SV[I]; 409 if (V == nullptr || SV[I] == CV[I]) 410 continue; 411 412 Instruction *Old = cast<Instruction>(V); 413 if (isa<Instruction>(CV[I])) 414 CV[I]->takeName(Old); 415 Old->replaceAllUsesWith(CV[I]); 416 PotentiallyDeadInstrs.emplace_back(Old); 417 } 418 } 419 SV = CV; 420 Gathered.push_back(GatherList::value_type(Op, &SV)); 421 } 422 423 // Return true if it is safe to transfer the given metadata tag from 424 // vector to scalar instructions. 425 bool ScalarizerVisitor::canTransferMetadata(unsigned Tag) { 426 return (Tag == LLVMContext::MD_tbaa 427 || Tag == LLVMContext::MD_fpmath 428 || Tag == LLVMContext::MD_tbaa_struct 429 || Tag == LLVMContext::MD_invariant_load 430 || Tag == LLVMContext::MD_alias_scope 431 || Tag == LLVMContext::MD_noalias 432 || Tag == ParallelLoopAccessMDKind 433 || Tag == LLVMContext::MD_access_group); 434 } 435 436 // Transfer metadata from Op to the instructions in CV if it is known 437 // to be safe to do so. 438 void ScalarizerVisitor::transferMetadataAndIRFlags(Instruction *Op, 439 const ValueVector &CV) { 440 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; 441 Op->getAllMetadataOtherThanDebugLoc(MDs); 442 for (unsigned I = 0, E = CV.size(); I != E; ++I) { 443 if (Instruction *New = dyn_cast<Instruction>(CV[I])) { 444 for (const auto &MD : MDs) 445 if (canTransferMetadata(MD.first)) 446 New->setMetadata(MD.first, MD.second); 447 New->copyIRFlags(Op); 448 if (Op->getDebugLoc() && !New->getDebugLoc()) 449 New->setDebugLoc(Op->getDebugLoc()); 450 } 451 } 452 } 453 454 // Try to fill in Layout from Ty, returning true on success. Alignment is 455 // the alignment of the vector, or None if the ABI default should be used. 456 Optional<VectorLayout> 457 ScalarizerVisitor::getVectorLayout(Type *Ty, Align Alignment, 458 const DataLayout &DL) { 459 VectorLayout Layout; 460 // Make sure we're dealing with a vector. 461 Layout.VecTy = dyn_cast<VectorType>(Ty); 462 if (!Layout.VecTy) 463 return None; 464 // Check that we're dealing with full-byte elements. 465 Layout.ElemTy = Layout.VecTy->getElementType(); 466 if (!DL.typeSizeEqualsStoreSize(Layout.ElemTy)) 467 return None; 468 Layout.VecAlign = Alignment; 469 Layout.ElemSize = DL.getTypeStoreSize(Layout.ElemTy); 470 return Layout; 471 } 472 473 // Scalarize one-operand instruction I, using Split(Builder, X, Name) 474 // to create an instruction like I with operand X and name Name. 475 template<typename Splitter> 476 bool ScalarizerVisitor::splitUnary(Instruction &I, const Splitter &Split) { 477 VectorType *VT = dyn_cast<VectorType>(I.getType()); 478 if (!VT) 479 return false; 480 481 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 482 IRBuilder<> Builder(&I); 483 Scatterer Op = scatter(&I, I.getOperand(0)); 484 assert(Op.size() == NumElems && "Mismatched unary operation"); 485 ValueVector Res; 486 Res.resize(NumElems); 487 for (unsigned Elem = 0; Elem < NumElems; ++Elem) 488 Res[Elem] = Split(Builder, Op[Elem], I.getName() + ".i" + Twine(Elem)); 489 gather(&I, Res); 490 return true; 491 } 492 493 // Scalarize two-operand instruction I, using Split(Builder, X, Y, Name) 494 // to create an instruction like I with operands X and Y and name Name. 495 template<typename Splitter> 496 bool ScalarizerVisitor::splitBinary(Instruction &I, const Splitter &Split) { 497 VectorType *VT = dyn_cast<VectorType>(I.getType()); 498 if (!VT) 499 return false; 500 501 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 502 IRBuilder<> Builder(&I); 503 Scatterer VOp0 = scatter(&I, I.getOperand(0)); 504 Scatterer VOp1 = scatter(&I, I.getOperand(1)); 505 assert(VOp0.size() == NumElems && "Mismatched binary operation"); 506 assert(VOp1.size() == NumElems && "Mismatched binary operation"); 507 ValueVector Res; 508 Res.resize(NumElems); 509 for (unsigned Elem = 0; Elem < NumElems; ++Elem) { 510 Value *Op0 = VOp0[Elem]; 511 Value *Op1 = VOp1[Elem]; 512 Res[Elem] = Split(Builder, Op0, Op1, I.getName() + ".i" + Twine(Elem)); 513 } 514 gather(&I, Res); 515 return true; 516 } 517 518 static bool isTriviallyScalariable(Intrinsic::ID ID) { 519 return isTriviallyVectorizable(ID); 520 } 521 522 // All of the current scalarizable intrinsics only have one mangled type. 523 static Function *getScalarIntrinsicDeclaration(Module *M, 524 Intrinsic::ID ID, 525 ArrayRef<Type*> Tys) { 526 return Intrinsic::getDeclaration(M, ID, Tys); 527 } 528 529 /// If a call to a vector typed intrinsic function, split into a scalar call per 530 /// element if possible for the intrinsic. 531 bool ScalarizerVisitor::splitCall(CallInst &CI) { 532 VectorType *VT = dyn_cast<VectorType>(CI.getType()); 533 if (!VT) 534 return false; 535 536 Function *F = CI.getCalledFunction(); 537 if (!F) 538 return false; 539 540 Intrinsic::ID ID = F->getIntrinsicID(); 541 if (ID == Intrinsic::not_intrinsic || !isTriviallyScalariable(ID)) 542 return false; 543 544 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 545 unsigned NumArgs = CI.arg_size(); 546 547 ValueVector ScalarOperands(NumArgs); 548 SmallVector<Scatterer, 8> Scattered(NumArgs); 549 550 Scattered.resize(NumArgs); 551 552 SmallVector<llvm::Type *, 3> Tys; 553 Tys.push_back(VT->getScalarType()); 554 555 // Assumes that any vector type has the same number of elements as the return 556 // vector type, which is true for all current intrinsics. 557 for (unsigned I = 0; I != NumArgs; ++I) { 558 Value *OpI = CI.getOperand(I); 559 if (OpI->getType()->isVectorTy()) { 560 Scattered[I] = scatter(&CI, OpI); 561 assert(Scattered[I].size() == NumElems && "mismatched call operands"); 562 } else { 563 ScalarOperands[I] = OpI; 564 if (hasVectorInstrinsicOverloadedScalarOpd(ID, I)) 565 Tys.push_back(OpI->getType()); 566 } 567 } 568 569 ValueVector Res(NumElems); 570 ValueVector ScalarCallOps(NumArgs); 571 572 Function *NewIntrin = getScalarIntrinsicDeclaration(F->getParent(), ID, Tys); 573 IRBuilder<> Builder(&CI); 574 575 // Perform actual scalarization, taking care to preserve any scalar operands. 576 for (unsigned Elem = 0; Elem < NumElems; ++Elem) { 577 ScalarCallOps.clear(); 578 579 for (unsigned J = 0; J != NumArgs; ++J) { 580 if (hasVectorInstrinsicScalarOpd(ID, J)) 581 ScalarCallOps.push_back(ScalarOperands[J]); 582 else 583 ScalarCallOps.push_back(Scattered[J][Elem]); 584 } 585 586 Res[Elem] = Builder.CreateCall(NewIntrin, ScalarCallOps, 587 CI.getName() + ".i" + Twine(Elem)); 588 } 589 590 gather(&CI, Res); 591 return true; 592 } 593 594 bool ScalarizerVisitor::visitSelectInst(SelectInst &SI) { 595 VectorType *VT = dyn_cast<VectorType>(SI.getType()); 596 if (!VT) 597 return false; 598 599 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 600 IRBuilder<> Builder(&SI); 601 Scatterer VOp1 = scatter(&SI, SI.getOperand(1)); 602 Scatterer VOp2 = scatter(&SI, SI.getOperand(2)); 603 assert(VOp1.size() == NumElems && "Mismatched select"); 604 assert(VOp2.size() == NumElems && "Mismatched select"); 605 ValueVector Res; 606 Res.resize(NumElems); 607 608 if (SI.getOperand(0)->getType()->isVectorTy()) { 609 Scatterer VOp0 = scatter(&SI, SI.getOperand(0)); 610 assert(VOp0.size() == NumElems && "Mismatched select"); 611 for (unsigned I = 0; I < NumElems; ++I) { 612 Value *Op0 = VOp0[I]; 613 Value *Op1 = VOp1[I]; 614 Value *Op2 = VOp2[I]; 615 Res[I] = Builder.CreateSelect(Op0, Op1, Op2, 616 SI.getName() + ".i" + Twine(I)); 617 } 618 } else { 619 Value *Op0 = SI.getOperand(0); 620 for (unsigned I = 0; I < NumElems; ++I) { 621 Value *Op1 = VOp1[I]; 622 Value *Op2 = VOp2[I]; 623 Res[I] = Builder.CreateSelect(Op0, Op1, Op2, 624 SI.getName() + ".i" + Twine(I)); 625 } 626 } 627 gather(&SI, Res); 628 return true; 629 } 630 631 bool ScalarizerVisitor::visitICmpInst(ICmpInst &ICI) { 632 return splitBinary(ICI, ICmpSplitter(ICI)); 633 } 634 635 bool ScalarizerVisitor::visitFCmpInst(FCmpInst &FCI) { 636 return splitBinary(FCI, FCmpSplitter(FCI)); 637 } 638 639 bool ScalarizerVisitor::visitUnaryOperator(UnaryOperator &UO) { 640 return splitUnary(UO, UnarySplitter(UO)); 641 } 642 643 bool ScalarizerVisitor::visitBinaryOperator(BinaryOperator &BO) { 644 return splitBinary(BO, BinarySplitter(BO)); 645 } 646 647 bool ScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) { 648 VectorType *VT = dyn_cast<VectorType>(GEPI.getType()); 649 if (!VT) 650 return false; 651 652 IRBuilder<> Builder(&GEPI); 653 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 654 unsigned NumIndices = GEPI.getNumIndices(); 655 656 // The base pointer might be scalar even if it's a vector GEP. In those cases, 657 // splat the pointer into a vector value, and scatter that vector. 658 Value *Op0 = GEPI.getOperand(0); 659 if (!Op0->getType()->isVectorTy()) 660 Op0 = Builder.CreateVectorSplat(NumElems, Op0); 661 Scatterer Base = scatter(&GEPI, Op0); 662 663 SmallVector<Scatterer, 8> Ops; 664 Ops.resize(NumIndices); 665 for (unsigned I = 0; I < NumIndices; ++I) { 666 Value *Op = GEPI.getOperand(I + 1); 667 668 // The indices might be scalars even if it's a vector GEP. In those cases, 669 // splat the scalar into a vector value, and scatter that vector. 670 if (!Op->getType()->isVectorTy()) 671 Op = Builder.CreateVectorSplat(NumElems, Op); 672 673 Ops[I] = scatter(&GEPI, Op); 674 } 675 676 ValueVector Res; 677 Res.resize(NumElems); 678 for (unsigned I = 0; I < NumElems; ++I) { 679 SmallVector<Value *, 8> Indices; 680 Indices.resize(NumIndices); 681 for (unsigned J = 0; J < NumIndices; ++J) 682 Indices[J] = Ops[J][I]; 683 Res[I] = Builder.CreateGEP(GEPI.getSourceElementType(), Base[I], Indices, 684 GEPI.getName() + ".i" + Twine(I)); 685 if (GEPI.isInBounds()) 686 if (GetElementPtrInst *NewGEPI = dyn_cast<GetElementPtrInst>(Res[I])) 687 NewGEPI->setIsInBounds(); 688 } 689 gather(&GEPI, Res); 690 return true; 691 } 692 693 bool ScalarizerVisitor::visitCastInst(CastInst &CI) { 694 VectorType *VT = dyn_cast<VectorType>(CI.getDestTy()); 695 if (!VT) 696 return false; 697 698 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 699 IRBuilder<> Builder(&CI); 700 Scatterer Op0 = scatter(&CI, CI.getOperand(0)); 701 assert(Op0.size() == NumElems && "Mismatched cast"); 702 ValueVector Res; 703 Res.resize(NumElems); 704 for (unsigned I = 0; I < NumElems; ++I) 705 Res[I] = Builder.CreateCast(CI.getOpcode(), Op0[I], VT->getElementType(), 706 CI.getName() + ".i" + Twine(I)); 707 gather(&CI, Res); 708 return true; 709 } 710 711 bool ScalarizerVisitor::visitBitCastInst(BitCastInst &BCI) { 712 VectorType *DstVT = dyn_cast<VectorType>(BCI.getDestTy()); 713 VectorType *SrcVT = dyn_cast<VectorType>(BCI.getSrcTy()); 714 if (!DstVT || !SrcVT) 715 return false; 716 717 unsigned DstNumElems = cast<FixedVectorType>(DstVT)->getNumElements(); 718 unsigned SrcNumElems = cast<FixedVectorType>(SrcVT)->getNumElements(); 719 IRBuilder<> Builder(&BCI); 720 Scatterer Op0 = scatter(&BCI, BCI.getOperand(0)); 721 ValueVector Res; 722 Res.resize(DstNumElems); 723 724 if (DstNumElems == SrcNumElems) { 725 for (unsigned I = 0; I < DstNumElems; ++I) 726 Res[I] = Builder.CreateBitCast(Op0[I], DstVT->getElementType(), 727 BCI.getName() + ".i" + Twine(I)); 728 } else if (DstNumElems > SrcNumElems) { 729 // <M x t1> -> <N*M x t2>. Convert each t1 to <N x t2> and copy the 730 // individual elements to the destination. 731 unsigned FanOut = DstNumElems / SrcNumElems; 732 auto *MidTy = FixedVectorType::get(DstVT->getElementType(), FanOut); 733 unsigned ResI = 0; 734 for (unsigned Op0I = 0; Op0I < SrcNumElems; ++Op0I) { 735 Value *V = Op0[Op0I]; 736 Instruction *VI; 737 // Look through any existing bitcasts before converting to <N x t2>. 738 // In the best case, the resulting conversion might be a no-op. 739 while ((VI = dyn_cast<Instruction>(V)) && 740 VI->getOpcode() == Instruction::BitCast) 741 V = VI->getOperand(0); 742 V = Builder.CreateBitCast(V, MidTy, V->getName() + ".cast"); 743 Scatterer Mid = scatter(&BCI, V); 744 for (unsigned MidI = 0; MidI < FanOut; ++MidI) 745 Res[ResI++] = Mid[MidI]; 746 } 747 } else { 748 // <N*M x t1> -> <M x t2>. Convert each group of <N x t1> into a t2. 749 unsigned FanIn = SrcNumElems / DstNumElems; 750 auto *MidTy = FixedVectorType::get(SrcVT->getElementType(), FanIn); 751 unsigned Op0I = 0; 752 for (unsigned ResI = 0; ResI < DstNumElems; ++ResI) { 753 Value *V = PoisonValue::get(MidTy); 754 for (unsigned MidI = 0; MidI < FanIn; ++MidI) 755 V = Builder.CreateInsertElement(V, Op0[Op0I++], Builder.getInt32(MidI), 756 BCI.getName() + ".i" + Twine(ResI) 757 + ".upto" + Twine(MidI)); 758 Res[ResI] = Builder.CreateBitCast(V, DstVT->getElementType(), 759 BCI.getName() + ".i" + Twine(ResI)); 760 } 761 } 762 gather(&BCI, Res); 763 return true; 764 } 765 766 bool ScalarizerVisitor::visitInsertElementInst(InsertElementInst &IEI) { 767 VectorType *VT = dyn_cast<VectorType>(IEI.getType()); 768 if (!VT) 769 return false; 770 771 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 772 IRBuilder<> Builder(&IEI); 773 Scatterer Op0 = scatter(&IEI, IEI.getOperand(0)); 774 Value *NewElt = IEI.getOperand(1); 775 Value *InsIdx = IEI.getOperand(2); 776 777 ValueVector Res; 778 Res.resize(NumElems); 779 780 if (auto *CI = dyn_cast<ConstantInt>(InsIdx)) { 781 for (unsigned I = 0; I < NumElems; ++I) 782 Res[I] = CI->getValue().getZExtValue() == I ? NewElt : Op0[I]; 783 } else { 784 if (!ScalarizeVariableInsertExtract) 785 return false; 786 787 for (unsigned I = 0; I < NumElems; ++I) { 788 Value *ShouldReplace = 789 Builder.CreateICmpEQ(InsIdx, ConstantInt::get(InsIdx->getType(), I), 790 InsIdx->getName() + ".is." + Twine(I)); 791 Value *OldElt = Op0[I]; 792 Res[I] = Builder.CreateSelect(ShouldReplace, NewElt, OldElt, 793 IEI.getName() + ".i" + Twine(I)); 794 } 795 } 796 797 gather(&IEI, Res); 798 return true; 799 } 800 801 bool ScalarizerVisitor::visitExtractElementInst(ExtractElementInst &EEI) { 802 VectorType *VT = dyn_cast<VectorType>(EEI.getOperand(0)->getType()); 803 if (!VT) 804 return false; 805 806 unsigned NumSrcElems = cast<FixedVectorType>(VT)->getNumElements(); 807 IRBuilder<> Builder(&EEI); 808 Scatterer Op0 = scatter(&EEI, EEI.getOperand(0)); 809 Value *ExtIdx = EEI.getOperand(1); 810 811 if (auto *CI = dyn_cast<ConstantInt>(ExtIdx)) { 812 Value *Res = Op0[CI->getValue().getZExtValue()]; 813 gather(&EEI, {Res}); 814 return true; 815 } 816 817 if (!ScalarizeVariableInsertExtract) 818 return false; 819 820 Value *Res = UndefValue::get(VT->getElementType()); 821 for (unsigned I = 0; I < NumSrcElems; ++I) { 822 Value *ShouldExtract = 823 Builder.CreateICmpEQ(ExtIdx, ConstantInt::get(ExtIdx->getType(), I), 824 ExtIdx->getName() + ".is." + Twine(I)); 825 Value *Elt = Op0[I]; 826 Res = Builder.CreateSelect(ShouldExtract, Elt, Res, 827 EEI.getName() + ".upto" + Twine(I)); 828 } 829 gather(&EEI, {Res}); 830 return true; 831 } 832 833 bool ScalarizerVisitor::visitShuffleVectorInst(ShuffleVectorInst &SVI) { 834 VectorType *VT = dyn_cast<VectorType>(SVI.getType()); 835 if (!VT) 836 return false; 837 838 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 839 Scatterer Op0 = scatter(&SVI, SVI.getOperand(0)); 840 Scatterer Op1 = scatter(&SVI, SVI.getOperand(1)); 841 ValueVector Res; 842 Res.resize(NumElems); 843 844 for (unsigned I = 0; I < NumElems; ++I) { 845 int Selector = SVI.getMaskValue(I); 846 if (Selector < 0) 847 Res[I] = UndefValue::get(VT->getElementType()); 848 else if (unsigned(Selector) < Op0.size()) 849 Res[I] = Op0[Selector]; 850 else 851 Res[I] = Op1[Selector - Op0.size()]; 852 } 853 gather(&SVI, Res); 854 return true; 855 } 856 857 bool ScalarizerVisitor::visitPHINode(PHINode &PHI) { 858 VectorType *VT = dyn_cast<VectorType>(PHI.getType()); 859 if (!VT) 860 return false; 861 862 unsigned NumElems = cast<FixedVectorType>(VT)->getNumElements(); 863 IRBuilder<> Builder(&PHI); 864 ValueVector Res; 865 Res.resize(NumElems); 866 867 unsigned NumOps = PHI.getNumOperands(); 868 for (unsigned I = 0; I < NumElems; ++I) 869 Res[I] = Builder.CreatePHI(VT->getElementType(), NumOps, 870 PHI.getName() + ".i" + Twine(I)); 871 872 for (unsigned I = 0; I < NumOps; ++I) { 873 Scatterer Op = scatter(&PHI, PHI.getIncomingValue(I)); 874 BasicBlock *IncomingBlock = PHI.getIncomingBlock(I); 875 for (unsigned J = 0; J < NumElems; ++J) 876 cast<PHINode>(Res[J])->addIncoming(Op[J], IncomingBlock); 877 } 878 gather(&PHI, Res); 879 return true; 880 } 881 882 bool ScalarizerVisitor::visitLoadInst(LoadInst &LI) { 883 if (!ScalarizeLoadStore) 884 return false; 885 if (!LI.isSimple()) 886 return false; 887 888 Optional<VectorLayout> Layout = getVectorLayout( 889 LI.getType(), LI.getAlign(), LI.getModule()->getDataLayout()); 890 if (!Layout) 891 return false; 892 893 unsigned NumElems = cast<FixedVectorType>(Layout->VecTy)->getNumElements(); 894 IRBuilder<> Builder(&LI); 895 Scatterer Ptr = scatter(&LI, LI.getPointerOperand(), LI.getType()); 896 ValueVector Res; 897 Res.resize(NumElems); 898 899 for (unsigned I = 0; I < NumElems; ++I) 900 Res[I] = Builder.CreateAlignedLoad(Layout->VecTy->getElementType(), Ptr[I], 901 Align(Layout->getElemAlign(I)), 902 LI.getName() + ".i" + Twine(I)); 903 gather(&LI, Res); 904 return true; 905 } 906 907 bool ScalarizerVisitor::visitStoreInst(StoreInst &SI) { 908 if (!ScalarizeLoadStore) 909 return false; 910 if (!SI.isSimple()) 911 return false; 912 913 Value *FullValue = SI.getValueOperand(); 914 Optional<VectorLayout> Layout = getVectorLayout( 915 FullValue->getType(), SI.getAlign(), SI.getModule()->getDataLayout()); 916 if (!Layout) 917 return false; 918 919 unsigned NumElems = cast<FixedVectorType>(Layout->VecTy)->getNumElements(); 920 IRBuilder<> Builder(&SI); 921 Scatterer VPtr = scatter(&SI, SI.getPointerOperand(), FullValue->getType()); 922 Scatterer VVal = scatter(&SI, FullValue); 923 924 ValueVector Stores; 925 Stores.resize(NumElems); 926 for (unsigned I = 0; I < NumElems; ++I) { 927 Value *Val = VVal[I]; 928 Value *Ptr = VPtr[I]; 929 Stores[I] = Builder.CreateAlignedStore(Val, Ptr, Layout->getElemAlign(I)); 930 } 931 transferMetadataAndIRFlags(&SI, Stores); 932 return true; 933 } 934 935 bool ScalarizerVisitor::visitCallInst(CallInst &CI) { 936 return splitCall(CI); 937 } 938 939 // Delete the instructions that we scalarized. If a full vector result 940 // is still needed, recreate it using InsertElements. 941 bool ScalarizerVisitor::finish() { 942 // The presence of data in Gathered or Scattered indicates changes 943 // made to the Function. 944 if (Gathered.empty() && Scattered.empty()) 945 return false; 946 for (const auto &GMI : Gathered) { 947 Instruction *Op = GMI.first; 948 ValueVector &CV = *GMI.second; 949 if (!Op->use_empty()) { 950 // The value is still needed, so recreate it using a series of 951 // InsertElements. 952 Value *Res = PoisonValue::get(Op->getType()); 953 if (auto *Ty = dyn_cast<VectorType>(Op->getType())) { 954 BasicBlock *BB = Op->getParent(); 955 unsigned Count = cast<FixedVectorType>(Ty)->getNumElements(); 956 IRBuilder<> Builder(Op); 957 if (isa<PHINode>(Op)) 958 Builder.SetInsertPoint(BB, BB->getFirstInsertionPt()); 959 for (unsigned I = 0; I < Count; ++I) 960 Res = Builder.CreateInsertElement(Res, CV[I], Builder.getInt32(I), 961 Op->getName() + ".upto" + Twine(I)); 962 Res->takeName(Op); 963 } else { 964 assert(CV.size() == 1 && Op->getType() == CV[0]->getType()); 965 Res = CV[0]; 966 if (Op == Res) 967 continue; 968 } 969 Op->replaceAllUsesWith(Res); 970 } 971 PotentiallyDeadInstrs.emplace_back(Op); 972 } 973 Gathered.clear(); 974 Scattered.clear(); 975 976 RecursivelyDeleteTriviallyDeadInstructionsPermissive(PotentiallyDeadInstrs); 977 978 return true; 979 } 980 981 PreservedAnalyses ScalarizerPass::run(Function &F, FunctionAnalysisManager &AM) { 982 Module &M = *F.getParent(); 983 unsigned ParallelLoopAccessMDKind = 984 M.getContext().getMDKindID("llvm.mem.parallel_loop_access"); 985 DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F); 986 ScalarizerVisitor Impl(ParallelLoopAccessMDKind, DT); 987 bool Changed = Impl.visit(F); 988 PreservedAnalyses PA; 989 PA.preserve<DominatorTreeAnalysis>(); 990 return Changed ? PA : PreservedAnalyses::all(); 991 } 992