summaryrefslogtreecommitdiffstats
path: root/llvm/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
commitdfb8c3bbfcab611b98f6d8a532e67169bb46ece4 (patch)
tree2569cf1c8d2cf01fb6da62fd1daebbb62d1beb02 /llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp
parent09d7bfd88627b98075c5456a50fc314cc3ccf4e2 (diff)
downloadbcm5719-llvm-dfb8c3bbfcab611b98f6d8a532e67169bb46ece4.tar.gz
bcm5719-llvm-dfb8c3bbfcab611b98f6d8a532e67169bb46ece4.zip
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. llvm-svn: 119853
Diffstat (limited to 'llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp b/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp
index 35d02d97401..7df01f84357 100644
--- a/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/llvm/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;
OpenPOWER on IntegriCloud