From: Owen Anderson Date: Fri, 19 Nov 2010 22:15:03 +0000 (+0000) Subject: When folding addressing modes in CodeGenPrepare, attempt to look through PHI nodes X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d2f4174fcc69a3328076734fa3256b31e5b7f734;p=oota-llvm.git 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 --- diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp index 35d02d97401..7df01f84357 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 &SunkAddrs) { + // Try to collapse single-value PHI nodes. This is necessary to undo + // unprofitable PRE transformations. + Value *Repl = Addr; + if (isa(Addr) && MemoryInst->hasOneUse()) { + PHINode *P = cast(Addr); + Instruction *Consensus = 0; + unsigned NumUses = 0; + for (unsigned i = 0, e = P->getNumIncomingValues(); i != e; ++i) { + Instruction *Incoming = dyn_cast(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 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;