summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2011-02-20 08:38:20 +0000
committerNick Lewycky <nicholas@mxc.ca>2011-02-20 08:38:20 +0000
commitc8a1569950128cbaf9264f37210be4cdea5f4bd8 (patch)
tree4683c16f272a9cfa6bc1c1e1a0c6e148697eece3 /llvm/lib/Transforms/Utils/Local.cpp
parent080ea93779028e2f67b04351c8941e008d5e359e (diff)
downloadbcm5719-llvm-c8a1569950128cbaf9264f37210be4cdea5f4bd8.tar.gz
bcm5719-llvm-c8a1569950128cbaf9264f37210be4cdea5f4bd8.zip
Teach RecursivelyDeleteDeadPHINodes to handle multiple self-references. Patch
by Andrew Clinton! llvm-svn: 126077
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 30e88e976f2..063c76e9522 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/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);
OpenPOWER on IntegriCloud