refactor some code, no functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36037 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2007-04-15 00:07:55 +00:00
parent ea37270ef2
commit 3284d1f18a

View File

@@ -352,6 +352,7 @@ namespace {
bool isSigned, bool Inside, Instruction &IB); bool isSigned, bool Inside, Instruction &IB);
Instruction *PromoteCastOfAllocation(CastInst &CI, AllocationInst &AI); Instruction *PromoteCastOfAllocation(CastInst &CI, AllocationInst &AI);
Instruction *MatchBSwap(BinaryOperator &I); Instruction *MatchBSwap(BinaryOperator &I);
bool SimplifyStoreAtEndOfBlock(StoreInst &SI);
Value *EvaluateInDifferentType(Value *V, const Type *Ty, bool isSigned); Value *EvaluateInDifferentType(Value *V, const Type *Ty, bool isSigned);
}; };
@@ -8818,37 +8819,61 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
// ends with an unconditional branch, try to move it to the successor block. // ends with an unconditional branch, try to move it to the successor block.
BBI = &SI; ++BBI; BBI = &SI; ++BBI;
if (BranchInst *BI = dyn_cast<BranchInst>(BBI)) if (BranchInst *BI = dyn_cast<BranchInst>(BBI))
if (BI->isUnconditional()) { if (BI->isUnconditional())
if (SimplifyStoreAtEndOfBlock(SI))
return 0; // xform done!
return 0;
}
/// SimplifyStoreAtEndOfBlock - Turn things like:
/// if () { *P = v1; } else { *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 // 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. // 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. // if so, insert a PHI node (if needed) and move the stores down.
BasicBlock *Dest = BI->getSuccessor(0); BasicBlock *Dest = StoreBB->getTerminator()->getSuccessor(0);
// Determine whether Dest has exactly two predecessors and, if so, compute
// the other predecessor.
pred_iterator PI = pred_begin(Dest); pred_iterator PI = pred_begin(Dest);
BasicBlock *Other = 0; BasicBlock *Other = 0;
if (*PI != BI->getParent()) if (*PI != StoreBB)
Other = *PI; Other = *PI;
++PI; ++PI;
if (PI != pred_end(Dest)) { if (PI == pred_end(Dest))
if (*PI != BI->getParent()) return false;
if (*PI != StoreBB) {
if (Other) if (Other)
Other = 0; return false;
else
Other = *PI; Other = *PI;
if (++PI != pred_end(Dest))
Other = 0;
} }
if (Other) { // If only one other pred... if (++PI != pred_end(Dest))
BBI = Other->getTerminator(); return false;
BasicBlock::iterator BBI = Other->getTerminator();
BranchInst *OtherBr = dyn_cast<BranchInst>(BBI);
// Make sure this other block ends in an unconditional branch and that // Make sure this other block ends in an unconditional branch and that
// there is an instruction before the branch. // there is an instruction before the branch.
if (isa<BranchInst>(BBI) && cast<BranchInst>(BBI)->isUnconditional() && if (!OtherBr || !cast<BranchInst>(BBI)->isUnconditional() ||
BBI != Other->begin()) { BBI == Other->begin())
return false;
// See if the last instruction in other block is a store to the same location.
--BBI; --BBI;
StoreInst *OtherStore = dyn_cast<StoreInst>(BBI); StoreInst *OtherStore = dyn_cast<StoreInst>(BBI);
// If this instruction is a store to the same location. // If this instruction is a store to the same location.
if (OtherStore && OtherStore->getOperand(1) == SI.getOperand(1)) { if (!OtherStore || OtherStore->getOperand(1) != SI.getOperand(1))
return false;
// Okay, we know we can perform this transformation. Insert a PHI // Okay, we know we can perform this transformation. Insert a PHI
// node now if we need it. // node now if we need it.
Value *MergedVal = OtherStore->getOperand(0); Value *MergedVal = OtherStore->getOperand(0);
@@ -8871,13 +8896,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
EraseInstFromFunction(SI); EraseInstFromFunction(SI);
EraseInstFromFunction(*OtherStore); EraseInstFromFunction(*OtherStore);
++NumCombined; ++NumCombined;
return 0; return true;
}
}
}
}
return 0;
} }