diff options
Diffstat (limited to 'lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | lib/Analysis/InstructionSimplify.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 6953f16dc9..f9953e3c98 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -15,6 +15,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/Instructions.h" #include "llvm/Support/PatternMatch.h" using namespace llvm; @@ -311,3 +312,37 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD) { } } +/// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then +/// delete the From instruction. In addition to a basic RAUW, this does a +/// recursive simplification of the newly formed instructions. This catches +/// things where one simplification exposes other opportunities. This only +/// simplifies and deletes scalar operations, it does not change the CFG. +/// +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. + WeakVH FromHandle(From); + + while (!From->use_empty()) { + // Update the instruction to use the new value. + Use &U = From->use_begin().getUse(); + Instruction *User = cast<Instruction>(U.getUser()); + U = To; + + // 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; + } + } + From->eraseFromParent(); +} + |