From: Chris Lattner Date: Sun, 15 Apr 2007 01:02:18 +0000 (+0000) Subject: Extend store merging to support the 'if/then' version in addition to if/then/else. X-Git-Tag: android-x86-6.0-r1~1003^2~35590 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=31755a024d8056947d9500233f8bd2e41b06c132;p=android-x86%2Fexternal-llvm.git 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 ; [#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 ; [#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 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 92259a33d1e..7d8b8a4b7a1 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -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(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()) + 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(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(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(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(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(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(BBI)) ++BBI; InsertNewInstBefore(new StoreInst(MergedVal, SI.getOperand(1), OtherStore->isVolatile()), *BBI);