diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index eff1de77d3c7..92259a33d1e9 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -352,6 +352,7 @@ namespace { bool isSigned, bool Inside, Instruction &IB); Instruction *PromoteCastOfAllocation(CastInst &CI, AllocationInst &AI); Instruction *MatchBSwap(BinaryOperator &I); + bool SimplifyStoreAtEndOfBlock(StoreInst &SI); Value *EvaluateInDifferentType(Value *V, const Type *Ty, bool isSigned); }; @@ -8818,68 +8819,86 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { // ends with an unconditional branch, try to move it to the successor block. BBI = &SI; ++BBI; if (BranchInst *BI = dyn_cast(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(BBI) && cast(BBI)->isUnconditional() && - BBI != Other->begin()) { - --BBI; - StoreInst *OtherStore = dyn_cast(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(BBI)) ++BBI; - InsertNewInstBefore(new StoreInst(MergedVal, SI.getOperand(1), - OtherStore->isVolatile()), *BBI); - - // Nuke the old stores. - EraseInstFromFunction(SI); - EraseInstFromFunction(*OtherStore); - ++NumCombined; - return 0; - } - } - } - } + 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 + // 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); + + // Determine whether Dest has exactly two predecessors and, if so, compute + // the other predecessor. + pred_iterator PI = pred_begin(Dest); + BasicBlock *Other = 0; + if (*PI != StoreBB) + Other = *PI; + ++PI; + if (PI == pred_end(Dest)) + return false; + + if (*PI != StoreBB) { + if (Other) + return false; + Other = *PI; + } + if (++PI != pred_end(Dest)) + return false; + + + BasicBlock::iterator BBI = Other->getTerminator(); + BranchInst *OtherBr = dyn_cast(BBI); + + // Make sure this other block ends in an unconditional branch and that + // there is an instruction before the branch. + if (!OtherBr || !cast(BBI)->isUnconditional() || + BBI == Other->begin()) + return false; + + // See if the last instruction in other block is a store to the same location. + --BBI; + StoreInst *OtherStore = dyn_cast(BBI); + + // 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. + 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(BBI)) ++BBI; + InsertNewInstBefore(new StoreInst(MergedVal, SI.getOperand(1), + OtherStore->isVolatile()), *BBI); + + // Nuke the old stores. + EraseInstFromFunction(SI); + EraseInstFromFunction(*OtherStore); + ++NumCombined; + return true; +} + Instruction *InstCombiner::visitBranchInst(BranchInst &BI) { // Change br (not X), label True, label False to: br X, label False, True