Extend store merging to support the 'if/then' version in addition to if/then/else.

This sinks the two stores in this example into a single store in cond_next.  In this
case, it allows elimination of the load as well:

        store double 0.000000e+00, double* @s.3060
        %tmp3 = fcmp ogt double %tmp1, 5.000000e-01             ; <i1> [#uses=1]
        br i1 %tmp3, label %cond_true, label %cond_next
cond_true:              ; preds = %entry
        store double 1.000000e+00, double* @s.3060
        br label %cond_next
cond_next:              ; preds = %entry, %cond_true
        %tmp6 = load double* @s.3060            ; <double> [#uses=1]

This implements Transforms/InstCombine/store-merge.ll:test2


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36040 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-04-15 01:02:18 +00:00
parent 9838939b3a
commit 31755a024d

View File

@ -8830,64 +8830,98 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
/// if () { *P = v1; } else { *P = v2 }
/// into a phi node with a store in the successor.
///
/// Simplify things like:
/// *P = v1; if () { *P = v2; }
/// into a phi node with a store in the successor.
///
bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
BasicBlock *StoreBB = SI.getParent();
// 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 = StoreBB->getTerminator()->getSuccessor(0);
BasicBlock *DestBB = StoreBB->getTerminator()->getSuccessor(0);
// Determine whether Dest has exactly two predecessors and, if so, compute
// the other predecessor.
pred_iterator PI = pred_begin(Dest);
BasicBlock *Other = 0;
pred_iterator PI = pred_begin(DestBB);
BasicBlock *OtherBB = 0;
if (*PI != StoreBB)
Other = *PI;
OtherBB = *PI;
++PI;
if (PI == pred_end(Dest))
if (PI == pred_end(DestBB))
return false;
if (*PI != StoreBB) {
if (Other)
if (OtherBB)
return false;
Other = *PI;
OtherBB = *PI;
}
if (++PI != pred_end(Dest))
if (++PI != pred_end(DestBB))
return false;
BasicBlock::iterator BBI = Other->getTerminator();
// Verify that the other block ends in a branch and is not otherwise empty.
BasicBlock::iterator BBI = OtherBB->getTerminator();
BranchInst *OtherBr = dyn_cast<BranchInst>(BBI);
// Make sure this other block ends in an unconditional branch and that
// there is an instruction before the branch.
if (!OtherBr || !cast<BranchInst>(BBI)->isUnconditional() ||
BBI == Other->begin())
if (!OtherBr || BBI == OtherBB->begin())
return false;
// See if the last instruction in other block is a store to the same location.
--BBI;
StoreInst *OtherStore = dyn_cast<StoreInst>(BBI);
// If the other block ends in an unconditional branch, check for the 'if then
// else' case. there is an instruction before the branch.
StoreInst *OtherStore = 0;
if (OtherBr->isUnconditional()) {
// If this isn't a store, or isn't a store to the same location, bail out.
--BBI;
OtherStore = dyn_cast<StoreInst>(BBI);
if (!OtherStore || OtherStore->getOperand(1) != SI.getOperand(1))
return false;
} else {
// Otherwise, the other block ended with a conditional branch. If one of the
// destinations is StoreBB, then we have the if/then case.
if (OtherBr->getSuccessor(0) != StoreBB &&
OtherBr->getSuccessor(1) != StoreBB)
return false;
// Okay, we know that OtherBr now goes to Dest and StoreBB, so this is an
// if/then triangle. See if there is a store to the same ptr as SI that lives
// in OtherBB.
for (;; --BBI) {
// Check to see if we find the matching store.
if ((OtherStore = dyn_cast<StoreInst>(BBI))) {
if (OtherStore->getOperand(1) != SI.getOperand(1))
return false;
break;
}
// If we find something that may be using the stored value, or if we run out
// of instructions, we can't do the xform.
if (isa<LoadInst>(BBI) || BBI->mayWriteToMemory() ||
BBI == OtherBB->begin())
return false;
}
// In order to eliminate the store in OtherBr, we have to
// make sure nothing reads the stored value in StoreBB.
for (BasicBlock::iterator I = StoreBB->begin(); &*I != &SI; ++I) {
// FIXME: This should really be AA driven.
if (isa<LoadInst>(I) || I->mayWriteToMemory())
return false;
}
}
// If this instruction is a store to the same location.
if (!OtherStore || OtherStore->getOperand(1) != SI.getOperand(1))
return false;
// Okay, we know we can perform this transformation. Insert a PHI
// node now if we need it.
// 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());
PN->addIncoming(OtherStore->getOperand(0), OtherBB);
MergedVal = InsertNewInstBefore(PN, DestBB->front());
}
// Advance to a place where it is safe to insert the new store and
// insert it.
BBI = Dest->begin();
BBI = DestBB->begin();
while (isa<PHINode>(BBI)) ++BBI;
InsertNewInstBefore(new StoreInst(MergedVal, SI.getOperand(1),
OtherStore->isVolatile()), *BBI);