diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2013-02-24 15:34:43 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2013-02-24 15:34:43 +0000 |
commit | ee40b9a2d4f5d340baea3f02e5d7f51caaa6b1ec (patch) | |
tree | 06146827a61b9a081126d29fb70f2ac9ba5c5f8c /llvm/lib/Transforms | |
parent | b867fea5e631ba022fcd8047ba845e5a56a2ff98 (diff) | |
download | bcm5719-llvm-ee40b9a2d4f5d340baea3f02e5d7f51caaa6b1ec.tar.gz bcm5719-llvm-ee40b9a2d4f5d340baea3f02e5d7f51caaa6b1ec.zip |
CVP: If we have a PHI with an incoming select, try to skip the select.
This is a common pattern with dyn_cast and similar constructs, when the
PHI no longer depends on the select it can often be turned into a simpler
construct or even get hoisted out of the loop.
PR15340.
llvm-svn: 175995
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 4c3631b2700..995782e1bc6 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -21,6 +21,8 @@ #include "llvm/IR/Instructions.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/Local.h" using namespace llvm; @@ -97,12 +99,29 @@ bool CorrelatedValuePropagation::processPHI(PHINode *P) { Value *Incoming = P->getIncomingValue(i); if (isa<Constant>(Incoming)) continue; - Constant *C = LVI->getConstantOnEdge(P->getIncomingValue(i), - P->getIncomingBlock(i), - BB); - if (!C) continue; + Value *V = LVI->getConstantOnEdge(Incoming, P->getIncomingBlock(i), BB); - P->setIncomingValue(i, C); + // Look if the incoming value is a select with a constant but LVI tells us + // that the incoming value can never be that constant. In that case replace + // the incoming value with the other value of the select. This often allows + // us to remove the select later. + if (!V) { + SelectInst *SI = dyn_cast<SelectInst>(Incoming); + if (!SI) continue; + + Constant *C = dyn_cast<Constant>(SI->getFalseValue()); + if (!C) continue; + + if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, + P->getIncomingBlock(i), BB) != + LazyValueInfo::False) + continue; + + DEBUG(dbgs() << "CVP: Threading PHI over " << *SI << '\n'); + V = SI->getTrueValue(); + } + + P->setIncomingValue(i, V); Changed = true; } |