aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/CodeGenPrepare.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2010-11-19 22:15:03 +0000
committerOwen Anderson <resistor@mac.com>2010-11-19 22:15:03 +0000
commitd2f4174fcc69a3328076734fa3256b31e5b7f734 (patch)
treeb4b5219df4891aa42e6a69561bfdb4496cbbabac /lib/Transforms/Scalar/CodeGenPrepare.cpp
parent2aeb6121a19aca7c317619f7ec37d7a770e9f03b (diff)
When folding addressing modes in CodeGenPrepare, attempt to look through PHI nodes
if all the operands of the PHI are equivalent. This allows CodeGenPrepare to undo unprofitable PRE transforms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119853 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/CodeGenPrepare.cpp')
-rw-r--r--lib/Transforms/Scalar/CodeGenPrepare.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp
index 35d02d9740..7df01f8435 100644
--- a/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp
@@ -618,6 +618,32 @@ static bool IsNonLocalValue(Value *V, BasicBlock *BB) {
bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
const Type *AccessTy,
DenseMap<Value*,Value*> &SunkAddrs) {
+ // Try to collapse single-value PHI nodes. This is necessary to undo
+ // unprofitable PRE transformations.
+ Value *Repl = Addr;
+ if (isa<PHINode>(Addr) && MemoryInst->hasOneUse()) {
+ PHINode *P = cast<PHINode>(Addr);
+ Instruction *Consensus = 0;
+ unsigned NumUses = 0;
+ for (unsigned i = 0, e = P->getNumIncomingValues(); i != e; ++i) {
+ Instruction *Incoming = dyn_cast<Instruction>(P->getIncomingValue(i));
+ if (!Incoming || (Consensus && !Incoming->isIdenticalTo(Consensus))) {
+ Consensus = 0;
+ break;
+ }
+
+ if (!Consensus || Incoming->isIdenticalTo(Consensus)) {
+ if (Incoming->getNumUses() > NumUses) {
+ Consensus = Incoming;
+ NumUses = Incoming->getNumUses();
+ }
+ continue;
+ }
+ }
+
+ if (Consensus) Addr = Consensus;
+ }
+
// Figure out what addressing mode will be built up for this operation.
SmallVector<Instruction*, 16> AddrModeInsts;
ExtAddrMode AddrMode = AddressingModeMatcher::Match(Addr, AccessTy,MemoryInst,
@@ -725,10 +751,10 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
SunkAddr = new IntToPtrInst(Result, Addr->getType(), "sunkaddr",InsertPt);
}
- MemoryInst->replaceUsesOfWith(Addr, SunkAddr);
+ MemoryInst->replaceUsesOfWith(Repl, SunkAddr);
- if (Addr->use_empty()) {
- RecursivelyDeleteTriviallyDeadInstructions(Addr);
+ if (Repl->use_empty()) {
+ RecursivelyDeleteTriviallyDeadInstructions(Repl);
// This address is now available for reassignment, so erase the table entry;
// we don't want to match some completely different instruction.
SunkAddrs[Addr] = 0;