[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
sabre at nondot.org
Sat Apr 14 18:02:39 PDT 2007
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.747 -> 1.748
---
Log message:
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
---
Diffs of the changes: (+60 -26)
InstructionCombining.cpp | 86 ++++++++++++++++++++++++++++++++---------------
1 files changed, 60 insertions(+), 26 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.747 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.748
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.747 Sat Apr 14 19:07:55 2007
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat Apr 14 20:02:18 2007
@@ -8830,64 +8830,98 @@
/// 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 this instruction is a store to the same location.
- if (!OtherStore || OtherStore->getOperand(1) != SI.getOperand(1))
- return false;
+ // 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;
+ }
+ }
- // 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);
More information about the llvm-commits
mailing list