summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorWei Mi <wmi@google.com>2016-07-18 21:14:43 +0000
committerWei Mi <wmi@google.com>2016-07-18 21:14:43 +0000
commitf9afff71a2c79f4f6fd9f05871dc9ca5be5a70c3 (patch)
tree177c7facdb00e2771a59e7d4b0183162296d2d45 /llvm/lib
parent926db72a4d066923e0572cf2b798d9b6b29b68fb (diff)
downloadbcm5719-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.cpp89
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,
OpenPOWER on IntegriCloud