diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-02-20 08:38:20 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-02-20 08:38:20 +0000 |
commit | 1a4021a2be4a59e9f9010776cb6f72107241aeb5 (patch) | |
tree | 59dce8a24541e969143618cc518550d6441863ce /lib/Transforms/Utils/Local.cpp | |
parent | eafe863b6dc35f9ba5360685f300d16d0a5e0c3c (diff) |
Teach RecursivelyDeleteDeadPHINodes to handle multiple self-references. Patch
by Andrew Clinton!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126077 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/Local.cpp')
-rw-r--r-- | lib/Transforms/Utils/Local.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 30e88e976f..063c76e952 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -260,29 +260,45 @@ bool llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V) { return true; } +/// areAllUsesEqual - Check whether the uses of a value are all the same. +/// This is similar to Instruction::hasOneUse() except this will also return +/// true when there are multiple uses that all refer to the same value. +static bool areAllUsesEqual(Instruction *I) { + Value::use_iterator UI = I->use_begin(); + Value::use_iterator UE = I->use_end(); + if (UI == UE) + return false; + + User *TheUse = *UI; + for (++UI; UI != UE; ++UI) { + if (*UI != TheUse) + return false; + } + return true; +} + /// RecursivelyDeleteDeadPHINode - If the specified value is an effectively /// dead PHI node, due to being a def-use chain of single-use nodes that /// either forms a cycle or is terminated by a trivially dead instruction, /// delete it. If that makes any of its operands trivially dead, delete them /// too, recursively. Return true if the PHI node is actually deleted. -bool -llvm::RecursivelyDeleteDeadPHINode(PHINode *PN) { +bool llvm::RecursivelyDeleteDeadPHINode(PHINode *PN) { // We can remove a PHI if it is on a cycle in the def-use graph // where each node in the cycle has degree one, i.e. only one use, // and is an instruction with no side effects. - if (!PN->hasOneUse()) + if (!areAllUsesEqual(PN)) return false; bool Changed = false; SmallPtrSet<PHINode *, 4> PHIs; PHIs.insert(PN); for (Instruction *J = cast<Instruction>(*PN->use_begin()); - J->hasOneUse() && !J->mayHaveSideEffects(); + areAllUsesEqual(J) && !J->mayHaveSideEffects(); J = cast<Instruction>(*J->use_begin())) // If we find a PHI more than once, we're on a cycle that // won't prove fruitful. if (PHINode *JP = dyn_cast<PHINode>(J)) - if (!PHIs.insert(cast<PHINode>(JP))) { + if (!PHIs.insert(JP)) { // Break the cycle and delete the PHI and its operands. JP->replaceAllUsesWith(UndefValue::get(JP->getType())); (void)RecursivelyDeleteTriviallyDeadInstructions(JP); |