aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Vectorize
diff options
context:
space:
mode:
authorArnold Schwaighofer <aschwaighofer@apple.com>2013-10-12 18:56:27 +0000
committerArnold Schwaighofer <aschwaighofer@apple.com>2013-10-12 18:56:27 +0000
commit24732c3363a9a442c14cf236c3de1086cdee6000 (patch)
treebb13ff4e0f982feedf44dc9915df59f86a6ba4a0 /lib/Transforms/Vectorize
parentfe82a3e360fc850e7551f2f1f32b58e539182c68 (diff)
downloadexternal_llvm-24732c3363a9a442c14cf236c3de1086cdee6000.zip
external_llvm-24732c3363a9a442c14cf236c3de1086cdee6000.tar.gz
external_llvm-24732c3363a9a442c14cf236c3de1086cdee6000.tar.bz2
SLPVectorizer: Sort PHINodes based on their opcode
Before this patch we relied on the order of phi nodes when we looked for phi nodes of the same type. This could prevent vectorization of cases where there was a phi node of a second type in between phi nodes of some type. This is important for vectorization of an internal graphics kernel. On the test suite + external on x86_64 (and on a run on armv7s) it showed no impact on either performance or compile time. radar://15024459 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192537 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Vectorize')
-rw-r--r--lib/Transforms/Vectorize/SLPVectorizer.cpp67
1 files changed, 44 insertions, 23 deletions
diff --git a/lib/Transforms/Vectorize/SLPVectorizer.cpp b/lib/Transforms/Vectorize/SLPVectorizer.cpp
index b5a303e..af1c0e7 100644
--- a/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -2366,42 +2366,63 @@ static bool findBuildVector(InsertElementInst *IE,
return false;
}
+static bool PhiTypeSorterFunc(Value *V, Value *V2) {
+ return V->getType() < V2->getType();
+}
+
bool SLPVectorizer::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
bool Changed = false;
SmallVector<Value *, 4> Incoming;
- SmallSet<Instruction *, 16> VisitedInstrs;
+ SmallSet<Value *, 16> VisitedInstrs;
+
+ bool HaveVectorizedPhiNodes = true;
+ while (HaveVectorizedPhiNodes) {
+ HaveVectorizedPhiNodes = false;
+
+ // Collect the incoming values from the PHIs.
+ Incoming.clear();
+ for (BasicBlock::iterator instr = BB->begin(), ie = BB->end(); instr != ie;
+ ++instr) {
+ PHINode *P = dyn_cast<PHINode>(instr);
+ if (!P)
+ break;
- // Collect the incoming values from the PHIs.
- for (BasicBlock::iterator instr = BB->begin(), ie = BB->end(); instr != ie;
- ++instr) {
- PHINode *P = dyn_cast<PHINode>(instr);
+ if (!VisitedInstrs.count(P))
+ Incoming.push_back(P);
+ }
- if (!P)
- break;
+ // Sort by type.
+ std::stable_sort(Incoming.begin(), Incoming.end(), PhiTypeSorterFunc);
- // We may go through BB multiple times so skip the one we have checked.
- if (!VisitedInstrs.insert(instr))
- continue;
+ // Try to vectorize elements base on their type.
+ for (SmallVector<Value *, 4>::iterator IncIt = Incoming.begin(),
+ E = Incoming.end();
+ IncIt != E;) {
- // Stop constructing the list when you reach a different type.
- if (Incoming.size() && P->getType() != Incoming[0]->getType()) {
- if (tryToVectorizeList(Incoming, R)) {
- // We would like to start over since some instructions are deleted
- // and the iterator may become invalid value.
+ // Look for the next elements with the same type.
+ SmallVector<Value *, 4>::iterator SameTypeIt = IncIt;
+ while (SameTypeIt != E &&
+ (*SameTypeIt)->getType() == (*IncIt)->getType()) {
+ VisitedInstrs.insert(*SameTypeIt);
+ ++SameTypeIt;
+ }
+
+ // Try to vectorize them.
+ unsigned NumElts = (SameTypeIt - IncIt);
+ DEBUG(errs() << "SLP: Trying to vectorize starting at PHIs (" << NumElts << ")\n");
+ if (NumElts > 1 &&
+ tryToVectorizeList(ArrayRef<Value *>(IncIt, NumElts), R)) {
+ // Success start over because instructions might have been changed.
+ HaveVectorizedPhiNodes = true;
Changed = true;
- instr = BB->begin();
- ie = BB->end();
+ break;
}
- Incoming.clear();
+ // Start over at the next instruction of a differnt type (or the end).
+ IncIt = SameTypeIt;
}
-
- Incoming.push_back(P);
}
- if (Incoming.size() > 1)
- Changed |= tryToVectorizeList(Incoming, R);
-
VisitedInstrs.clear();
for (BasicBlock::iterator it = BB->begin(), e = BB->end(); it != e; it++) {