diff options
author | Chris Lattner <sabre@nondot.org> | 2005-09-12 23:23:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-09-12 23:23:25 +0000 |
commit | 408902b3c461e95799f97e6ac18cb107e1d58e46 (patch) | |
tree | d3d062e94d4833ce3b9af46283e7b8de0084d951 | |
parent | 15cc608a8f5b2ab2a0b5335f028482d5a012e3b4 (diff) |
Implement a simple xform to turn code like this:
if () { store A -> P; } else { store B -> P; }
into a PHI node with one store, in the most trival case. This implements
load.ll:test10.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23324 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index b508977cf3..ce66a028d6 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -5157,6 +5157,72 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { if (Instruction *Res = InstCombineStoreToCast(*this, SI)) return Res; + + // If this store is the last instruction in the basic block, and if the block + // ends with an unconditional branch, try to move it to the successor block. + BasicBlock::iterator BBI = &SI; ++BBI; + if (BranchInst *BI = dyn_cast<BranchInst>(BBI)) + if (BI->isUnconditional()) { + // Check to see if the successor block has exactly two incoming edges. If + // so, see if the other predecessor contains a store to the same location. + // if so, insert a PHI node (if needed) and move the stores down. + BasicBlock *Dest = BI->getSuccessor(0); + + pred_iterator PI = pred_begin(Dest); + BasicBlock *Other = 0; + if (*PI != BI->getParent()) + Other = *PI; + ++PI; + if (PI != pred_end(Dest)) { + if (*PI != BI->getParent()) + if (Other) + Other = 0; + else + Other = *PI; + if (++PI != pred_end(Dest)) + Other = 0; + } + if (Other) { // If only one other pred... + BBI = Other->getTerminator(); + // Make sure this other block ends in an unconditional branch and that + // there is an instruction before the branch. + if (isa<BranchInst>(BBI) && cast<BranchInst>(BBI)->isUnconditional() && + BBI != Other->begin()) { + --BBI; + StoreInst *OtherStore = dyn_cast<StoreInst>(BBI); + + // If this instruction is a store to the same location. + if (OtherStore && OtherStore->getOperand(1) == SI.getOperand(1)) { + // Okay, we know we can perform this transformation. Insert a PHI + // node now if we need it. + Value *MergedVal = OtherStore->getOperand(0); + if (MergedVal != SI.getOperand(0)) { + PHINode *PN = new PHINode(MergedVal->getType(), "storemerge"); + PN->reserveOperandSpace(2); + PN->addIncoming(SI.getOperand(0), SI.getParent()); + PN->addIncoming(OtherStore->getOperand(0), Other); + MergedVal = InsertNewInstBefore(PN, Dest->front()); + } + + // Advance to a place where it is safe to insert the new store and + // insert it. + BBI = Dest->begin(); + while (isa<PHINode>(BBI)) ++BBI; + InsertNewInstBefore(new StoreInst(MergedVal, SI.getOperand(1), + OtherStore->isVolatile()), *BBI); + + // Nuke the old stores. + removeFromWorkList(&SI); + removeFromWorkList(OtherStore); + SI.eraseFromParent(); + OtherStore->eraseFromParent(); + ++NumCombined; + return 0; + } + } + } + } + return 0; } |