1 //===- SLPVectorizer.cpp - A bottom up SLP Vectorizer ---------------------===// 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 // This pass implements the Bottom Up SLP vectorizer. It detects consecutive 10 // stores that can be put together into vector-stores. Next, it attempts to 11 // construct vectorizable tree using the use-def chains. If a profitable tree 12 // was found, the SLP vectorizer performs vectorization on the tree. 13 // 14 // The pass is inspired by the work described in the paper: 15 // "Loop-Aware SLP in GCC" by Ira Rosen, Dorit Nuzman, Ayal Zaks. 16 // 17 //===----------------------------------------------------------------------===// 18 #define SV_NAME "slp-vectorizer" 19 #define DEBUG_TYPE SV_NAME 20 21 #include "VecUtils.h" 22 #include "llvm/Transforms/Vectorize.h" 23 #include "llvm/ADT/MapVector.h" 24 #include "llvm/Analysis/AliasAnalysis.h" 25 #include "llvm/Analysis/ScalarEvolution.h" 26 #include "llvm/Analysis/TargetTransformInfo.h" 27 #include "llvm/Analysis/Verifier.h" 28 #include "llvm/Analysis/LoopInfo.h" 29 #include "llvm/IR/DataLayout.h" 30 #include "llvm/IR/Instructions.h" 31 #include "llvm/IR/IntrinsicInst.h" 32 #include "llvm/IR/Module.h" 33 #include "llvm/IR/Type.h" 34 #include "llvm/IR/Value.h" 35 #include "llvm/Pass.h" 36 #include "llvm/Support/CommandLine.h" 37 #include "llvm/Support/Debug.h" 38 #include "llvm/Support/raw_ostream.h" 39 #include <map> 40 41 using namespace llvm; 42 43 static cl::opt<int> 44 SLPCostThreshold("slp-threshold", cl::init(0), cl::Hidden, 45 cl::desc("Only vectorize trees if the gain is above this " 46 "number. (gain = -cost of vectorization)")); 47 namespace { 48 49 /// The SLPVectorizer Pass. 50 struct SLPVectorizer : public FunctionPass { 51 typedef MapVector<Value*, BoUpSLP::StoreList> StoreListMap; 52 53 /// Pass identification, replacement for typeid 54 static char ID; 55 56 explicit SLPVectorizer() : FunctionPass(ID) { 57 initializeSLPVectorizerPass(*PassRegistry::getPassRegistry()); 58 } 59 60 ScalarEvolution *SE; 61 DataLayout *DL; 62 TargetTransformInfo *TTI; 63 AliasAnalysis *AA; 64 LoopInfo *LI; 65 66 virtual bool runOnFunction(Function &F) { 67 SE = &getAnalysis<ScalarEvolution>(); 68 DL = getAnalysisIfAvailable<DataLayout>(); 69 TTI = &getAnalysis<TargetTransformInfo>(); 70 AA = &getAnalysis<AliasAnalysis>(); 71 LI = &getAnalysis<LoopInfo>(); 72 73 StoreRefs.clear(); 74 bool Changed = false; 75 76 // Must have DataLayout. We can't require it because some tests run w/o 77 // triple. 78 if (!DL) 79 return false; 80 81 DEBUG(dbgs()<<"SLP: Analyzing blocks in " << F.getName() << ".\n"); 82 83 for (Function::iterator it = F.begin(), e = F.end(); it != e; ++it) { 84 BasicBlock *BB = it; 85 bool BBChanged = false; 86 87 // Use the bollom up slp vectorizer to construct chains that start with 88 // he store instructions. 89 BoUpSLP R(BB, SE, DL, TTI, AA, LI->getLoopFor(BB)); 90 91 // Vectorize trees that end at reductions. 92 BBChanged |= vectorizeReductions(BB, R); 93 94 // Vectorize trees that end at stores. 95 if (unsigned count = collectStores(BB, R)) { 96 (void)count; 97 DEBUG(dbgs()<<"SLP: Found " << count << " stores to vectorize.\n"); 98 BBChanged |= vectorizeStoreChains(R); 99 } 100 101 // Try to hoist some of the scalarization code to the preheader. 102 if (BBChanged) hoistGatherSequence(LI, BB, R); 103 104 Changed |= BBChanged; 105 } 106 107 if (Changed) { 108 DEBUG(dbgs()<<"SLP: vectorized \""<<F.getName()<<"\"\n"); 109 DEBUG(verifyFunction(F)); 110 } 111 return Changed; 112 } 113 114 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 115 FunctionPass::getAnalysisUsage(AU); 116 AU.addRequired<ScalarEvolution>(); 117 AU.addRequired<AliasAnalysis>(); 118 AU.addRequired<TargetTransformInfo>(); 119 AU.addRequired<LoopInfo>(); 120 } 121 122 private: 123 124 /// \brief Collect memory references and sort them according to their base 125 /// object. We sort the stores to their base objects to reduce the cost of the 126 /// quadratic search on the stores. TODO: We can further reduce this cost 127 /// if we flush the chain creation every time we run into a memory barrier. 128 unsigned collectStores(BasicBlock *BB, BoUpSLP &R); 129 130 /// \brief Try to vectorize a chain that starts at two arithmetic instrs. 131 bool tryToVectorizePair(Value *A, Value *B, BoUpSLP &R); 132 133 /// \brief Try to vectorize a list of operands. 134 bool tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R); 135 136 /// \brief Try to vectorize a chain that may start at the operands of \V; 137 bool tryToVectorize(BinaryOperator *V, BoUpSLP &R); 138 139 /// \brief Vectorize the stores that were collected in StoreRefs. 140 bool vectorizeStoreChains(BoUpSLP &R); 141 142 /// \brief Try to hoist gather sequences outside of the loop in cases where 143 /// all of the sources are loop invariant. 144 void hoistGatherSequence(LoopInfo *LI, BasicBlock *BB, BoUpSLP &R); 145 146 /// \brief Scan the basic block and look for reductions that may start a 147 /// vectorization chain. 148 bool vectorizeReductions(BasicBlock *BB, BoUpSLP &R); 149 150 private: 151 StoreListMap StoreRefs; 152 }; 153 154 unsigned SLPVectorizer::collectStores(BasicBlock *BB, BoUpSLP &R) { 155 unsigned count = 0; 156 StoreRefs.clear(); 157 for (BasicBlock::iterator it = BB->begin(), e = BB->end(); it != e; ++it) { 158 StoreInst *SI = dyn_cast<StoreInst>(it); 159 if (!SI) 160 continue; 161 162 // Check that the pointer points to scalars. 163 Type *Ty = SI->getValueOperand()->getType(); 164 if (Ty->isAggregateType() || Ty->isVectorTy()) 165 return 0; 166 167 // Find the base of the GEP. 168 Value *Ptr = SI->getPointerOperand(); 169 if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr)) 170 Ptr = GEP->getPointerOperand(); 171 172 // Save the store locations. 173 StoreRefs[Ptr].push_back(SI); 174 count++; 175 } 176 return count; 177 } 178 179 bool SLPVectorizer::tryToVectorizePair(Value *A, Value *B, BoUpSLP &R) { 180 if (!A || !B) return false; 181 Value *VL[] = { A, B }; 182 return tryToVectorizeList(VL, R); 183 } 184 185 bool SLPVectorizer::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R) { 186 DEBUG(dbgs()<<"SLP: Vectorizing a list of length = " << VL.size() << ".\n"); 187 188 // Check that all of the parts are scalar. 189 for (int i = 0, e = VL.size(); i < e; ++i) { 190 Type *Ty = VL[i]->getType(); 191 if (Ty->isAggregateType() || Ty->isVectorTy()) 192 return 0; 193 } 194 195 int Cost = R.getTreeCost(VL); 196 int ExtrCost = R.getScalarizationCost(VL); 197 DEBUG(dbgs()<<"SLP: Cost of pair:" << Cost << 198 " Cost of extract:" << ExtrCost << ".\n"); 199 if ((Cost+ExtrCost) >= -SLPCostThreshold) return false; 200 DEBUG(dbgs()<<"SLP: Vectorizing pair.\n"); 201 R.vectorizeArith(VL); 202 return true; 203 } 204 205 bool SLPVectorizer::tryToVectorize(BinaryOperator *V, BoUpSLP &R) { 206 if (!V) return false; 207 // Try to vectorize V. 208 if (tryToVectorizePair(V->getOperand(0), V->getOperand(1), R)) 209 return true; 210 211 BinaryOperator *A = dyn_cast<BinaryOperator>(V->getOperand(0)); 212 BinaryOperator *B = dyn_cast<BinaryOperator>(V->getOperand(1)); 213 // Try to skip B. 214 if (B && B->hasOneUse()) { 215 BinaryOperator *B0 = dyn_cast<BinaryOperator>(B->getOperand(0)); 216 BinaryOperator *B1 = dyn_cast<BinaryOperator>(B->getOperand(1)); 217 if (tryToVectorizePair(A, B0, R)) { 218 B->moveBefore(V); 219 return true; 220 } 221 if (tryToVectorizePair(A, B1, R)) { 222 B->moveBefore(V); 223 return true; 224 } 225 } 226 227 // Try to skip A. 228 if (A && A->hasOneUse()) { 229 BinaryOperator *A0 = dyn_cast<BinaryOperator>(A->getOperand(0)); 230 BinaryOperator *A1 = dyn_cast<BinaryOperator>(A->getOperand(1)); 231 if (tryToVectorizePair(A0, B, R)) { 232 A->moveBefore(V); 233 return true; 234 } 235 if (tryToVectorizePair(A1, B, R)) { 236 A->moveBefore(V); 237 return true; 238 } 239 } 240 return 0; 241 } 242 243 bool SLPVectorizer::vectorizeReductions(BasicBlock *BB, BoUpSLP &R) { 244 bool Changed = false; 245 for (BasicBlock::iterator it = BB->begin(), e = BB->end(); it != e; ++it) { 246 if (isa<DbgInfoIntrinsic>(it)) continue; 247 248 // Try to vectorize reductions that use PHINodes. 249 if (PHINode *P = dyn_cast<PHINode>(it)) { 250 // Check that the PHI is a reduction PHI. 251 if (P->getNumIncomingValues() != 2) return Changed; 252 Value *Rdx = (P->getIncomingBlock(0) == BB ? P->getIncomingValue(0) : 253 (P->getIncomingBlock(1) == BB ? P->getIncomingValue(1) : 254 0)); 255 // Check if this is a Binary Operator. 256 BinaryOperator *BI = dyn_cast_or_null<BinaryOperator>(Rdx); 257 if (!BI) 258 continue; 259 260 Value *Inst = BI->getOperand(0); 261 if (Inst == P) Inst = BI->getOperand(1); 262 Changed |= tryToVectorize(dyn_cast<BinaryOperator>(Inst), R); 263 continue; 264 } 265 266 // Try to vectorize trees that start at compare instructions. 267 if (CmpInst *CI = dyn_cast<CmpInst>(it)) { 268 if (tryToVectorizePair(CI->getOperand(0), CI->getOperand(1), R)) { 269 Changed |= true; 270 continue; 271 } 272 for (int i = 0; i < 2; ++i) 273 if (BinaryOperator *BI = dyn_cast<BinaryOperator>(CI->getOperand(i))) 274 Changed |= tryToVectorizePair(BI->getOperand(0), BI->getOperand(1), R); 275 continue; 276 } 277 } 278 279 return Changed; 280 } 281 282 bool SLPVectorizer::vectorizeStoreChains(BoUpSLP &R) { 283 bool Changed = false; 284 // Attempt to sort and vectorize each of the store-groups. 285 for (StoreListMap::iterator it = StoreRefs.begin(), e = StoreRefs.end(); 286 it != e; ++it) { 287 if (it->second.size() < 2) 288 continue; 289 290 DEBUG(dbgs()<<"SLP: Analyzing a store chain of length " << 291 it->second.size() << ".\n"); 292 293 Changed |= R.vectorizeStores(it->second, -SLPCostThreshold); 294 } 295 return Changed; 296 } 297 298 void SLPVectorizer::hoistGatherSequence(LoopInfo *LI, BasicBlock *BB, 299 BoUpSLP &R) { 300 // Check if this block is inside a loop. 301 Loop *L = LI->getLoopFor(BB); 302 if (!L) 303 return; 304 305 // Check if it has a preheader. 306 BasicBlock *PreHeader = L->getLoopPreheader(); 307 if (!PreHeader) 308 return; 309 310 // Mark the insertion point for the block. 311 Instruction *Location = PreHeader->getTerminator(); 312 313 BoUpSLP::ValueList &Gathers = R.getGatherSeqInstructions(); 314 for (BoUpSLP::ValueList::iterator it = Gathers.begin(), e = Gathers.end(); 315 it != e; ++it) { 316 InsertElementInst *Insert = dyn_cast<InsertElementInst>(*it); 317 318 // The InsertElement sequence can be simplified into a constant. 319 if (!Insert) 320 continue; 321 322 // If the vector or the element that we insert into it are 323 // instructions that are defined in this basic block then we can't 324 // hoist this instruction. 325 Instruction *CurrVec = dyn_cast<Instruction>(Insert->getOperand(0)); 326 Instruction *NewElem = dyn_cast<Instruction>(Insert->getOperand(1)); 327 if (CurrVec && L->contains(CurrVec)) continue; 328 if (NewElem && L->contains(NewElem)) continue; 329 330 // We can hoist this instruction. Move it to the pre-header. 331 Insert->moveBefore(Location); 332 } 333 } 334 335 } // end anonymous namespace 336 337 char SLPVectorizer::ID = 0; 338 static const char lv_name[] = "SLP Vectorizer"; 339 INITIALIZE_PASS_BEGIN(SLPVectorizer, SV_NAME, lv_name, false, false) 340 INITIALIZE_AG_DEPENDENCY(AliasAnalysis) 341 INITIALIZE_AG_DEPENDENCY(TargetTransformInfo) 342 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) 343 INITIALIZE_PASS_DEPENDENCY(LoopSimplify) 344 INITIALIZE_PASS_END(SLPVectorizer, SV_NAME, lv_name, false, false) 345 346 namespace llvm { 347 Pass *createSLPVectorizerPass() { 348 return new SLPVectorizer(); 349 } 350 } 351 352