X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FAnalysis%2FInstructionSimplify.cpp;h=24cd3433a2cab25aa3a91ca68c8f7d100be93ee6;hb=bd4d66d56a4e761a206dac14ccff4d37139d9ad9;hp=0efe183a998b62cb10c01809d35fddcf50e9a313;hpb=3ed60a2a2253fd519a2b2e48cacce10856198b62;p=oota-llvm.git diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 0efe183a998..24cd3433a2c 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -440,29 +440,47 @@ void llvm::ReplaceAndSimplifyAllUses(Instruction *From, Value *To, const TargetData *TD) { assert(From != To && "ReplaceAndSimplifyAllUses(X,X) is not valid!"); - // FromHandle - This keeps a weakvh on the from value so that we can know if - // it gets deleted out from under us in a recursive simplification. + // FromHandle/ToHandle - This keeps a WeakVH on the from/to values so that + // we can know if it gets deleted out from under us or replaced in a + // recursive simplification. WeakVH FromHandle(From); - // Double-check that To isn't deleted. - AssertingVH<> CheckedTo = To; - + WeakVH ToHandle(To); + while (!From->use_empty()) { // Update the instruction to use the new value. - Use &U = From->use_begin().getUse(); - Instruction *User = cast(U.getUser()); - U = To; + Use &TheUse = From->use_begin().getUse(); + Instruction *User = cast(TheUse.getUser()); + TheUse = To; + + // Check to see if the instruction can be folded due to the operand + // replacement. For example changing (or X, Y) into (or X, -1) can replace + // the 'or' with -1. + Value *SimplifiedVal; + { + // Sanity check to make sure 'User' doesn't dangle across + // SimplifyInstruction. + AssertingVH<> UserHandle(User); - // See if we can simplify it. - if (Value *V = SimplifyInstruction(User, TD)) { - // Recursively simplify this. - ReplaceAndSimplifyAllUses(User, V, TD); - - // If the recursive simplification ended up revisiting and deleting 'From' - // then we're done. - if (FromHandle == 0) - return; + SimplifiedVal = SimplifyInstruction(User, TD); + if (SimplifiedVal == 0) continue; } + + // Recursively simplify this user to the new value. + ReplaceAndSimplifyAllUses(User, SimplifiedVal, TD); + From = dyn_cast_or_null((Value*)FromHandle); + To = ToHandle; + + assert(ToHandle && "To value deleted by recursive simplification?"); + + // If the recursive simplification ended up revisiting and deleting + // 'From' then we're done. + if (From == 0) + return; } + + // If 'From' has value handles referring to it, do a real RAUW to update them. + From->replaceAllUsesWith(To); + From->eraseFromParent(); }