diff options
| author | Wei Mi <wmi@google.com> | 2016-07-18 21:14:43 +0000 |
|---|---|---|
| committer | Wei Mi <wmi@google.com> | 2016-07-18 21:14:43 +0000 |
| commit | f9afff71a2c79f4f6fd9f05871dc9ca5be5a70c3 (patch) | |
| tree | 177c7facdb00e2771a59e7d4b0183162296d2d45 /llvm/lib | |
| parent | 926db72a4d066923e0572cf2b798d9b6b29b68fb (diff) | |
| download | bcm5719-llvm-f9afff71a2c79f4f6fd9f05871dc9ca5be5a70c3.tar.gz bcm5719-llvm-f9afff71a2c79f4f6fd9f05871dc9ca5be5a70c3.zip | |
Revert rL275912.
llvm-svn: 275915
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 89 |
1 files changed, 49 insertions, 40 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index d42c9cb6e84..8b85e320d3b 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -6156,16 +6156,6 @@ bool LoopVectorizationCostModel::isConsecutiveLoadOrStore(Instruction *Inst) { return false; } -/// Take the pointer operand from the Load/Store instruction. -/// Returns NULL if this is not a valid Load/Store instruction. -static Value *getPointerOperand(Value *I) { - if (LoadInst *LI = dyn_cast<LoadInst>(I)) - return LI->getPointerOperand(); - if (StoreInst *SI = dyn_cast<StoreInst>(I)) - return SI->getPointerOperand(); - return nullptr; -} - void LoopVectorizationCostModel::collectValuesToIgnore() { // Ignore ephemeral values. CodeMetrics::collectEphemeralValues(TheLoop, AC, ValuesToIgnore); @@ -6178,44 +6168,63 @@ void LoopVectorizationCostModel::collectValuesToIgnore() { VecValuesToIgnore.insert(Casts.begin(), Casts.end()); } - // Insert uniform instruction into VecValuesToIgnore. - // Collect non-gather/scatter and non-consecutive ptr in NonConsecutivePtr. - SmallPtrSet<Instruction *, 8> NonConsecutivePtr; - for (auto *BB : TheLoop->getBlocks()) { - for (auto &I : *BB) { - if (Legal->isUniformAfterVectorization(&I)) - VecValuesToIgnore.insert(&I); - Instruction *PI = dyn_cast_or_null<Instruction>(getPointerOperand(&I)); - if (PI && !Legal->isConsecutivePtr(PI) && - !isGatherOrScatterLegal(&I, PI, Legal)) - NonConsecutivePtr.insert(PI); - } - } - - // Ignore induction phis that are either used in uniform instructions or - // NonConsecutivePtr. + // Ignore induction phis that are only used in either GetElementPtr or ICmp + // instruction to exit loop. Induction variables usually have large types and + // can have big impact when estimating register usage. + // This is for when VF > 1. for (auto &Induction : *Legal->getInductionVars()) { auto *PN = Induction.first; auto *UpdateV = PN->getIncomingValueForBlock(TheLoop->getLoopLatch()); - if (std::all_of(PN->user_begin(), PN->user_end(), - [&](User *U) -> bool { - Instruction *UI = dyn_cast<Instruction>(U); - return U == UpdateV || !TheLoop->contains(UI) || - Legal->isUniformAfterVectorization(UI) || - NonConsecutivePtr.count(UI); - }) && - std::all_of(UpdateV->user_begin(), UpdateV->user_end(), - [&](User *U) -> bool { - Instruction *UI = dyn_cast<Instruction>(U); - return U == PN || !TheLoop->contains(UI) || - Legal->isUniformAfterVectorization(UI) || - NonConsecutivePtr.count(UI); - })) { + // Check that the PHI is only used by the induction increment (UpdateV) or + // by GEPs. Then check that UpdateV is only used by a compare instruction, + // the loop header PHI, or by GEPs. + // FIXME: Need precise def-use analysis to determine if this instruction + // variable will be vectorized. + if (all_of(PN->users(), + [&](const User *U) -> bool { + return U == UpdateV || isa<GetElementPtrInst>(U); + }) && + all_of(UpdateV->users(), [&](const User *U) -> bool { + return U == PN || isa<ICmpInst>(U) || isa<GetElementPtrInst>(U); + })) { VecValuesToIgnore.insert(PN); VecValuesToIgnore.insert(UpdateV); } } + + // Ignore instructions that will not be vectorized. + // This is for when VF > 1. + for (BasicBlock *BB : TheLoop->blocks()) { + for (auto &Inst : *BB) { + switch (Inst.getOpcode()) + case Instruction::GetElementPtr: { + // Ignore GEP if its last operand is an induction variable so that it is + // a consecutive load/store and won't be vectorized as scatter/gather + // pattern. + + GetElementPtrInst *Gep = cast<GetElementPtrInst>(&Inst); + unsigned NumOperands = Gep->getNumOperands(); + unsigned InductionOperand = getGEPInductionOperand(Gep); + bool GepToIgnore = true; + + // Check that all of the gep indices are uniform except for the + // induction operand. + for (unsigned i = 0; i != NumOperands; ++i) { + if (i != InductionOperand && + !PSE.getSE()->isLoopInvariant(PSE.getSCEV(Gep->getOperand(i)), + TheLoop)) { + GepToIgnore = false; + break; + } + } + + if (GepToIgnore) + VecValuesToIgnore.insert(&Inst); + break; + } + } + } } void InnerLoopUnroller::scalarizeInstruction(Instruction *Instr, |

