summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-06-29 05:25:23 +0000
committerChris Lattner <sabre@nondot.org>2001-06-29 05:25:23 +0000
commitb47af25099cac5c59795d6f1eb3b7cf9f962b32f (patch)
tree768a1c48807e12de4f6f4cc3d5543cdff4a958d8 /lib
parent25d17a5001648a8f944665643c8b4e9699b324a7 (diff)
downloadllvm-b47af25099cac5c59795d6f1eb3b7cf9f962b32f.tar.gz
llvm-b47af25099cac5c59795d6f1eb3b7cf9f962b32f.tar.bz2
llvm-b47af25099cac5c59795d6f1eb3b7cf9f962b32f.tar.xz
Add implementation of BasicBlock::removePredecessor code that was factored
out of DCE.cpp git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/VMCore/BasicBlock.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp
index 36ad93d477..8fee4eff58 100644
--- a/lib/VMCore/BasicBlock.cpp
+++ b/lib/VMCore/BasicBlock.cpp
@@ -11,6 +11,8 @@
#include "llvm/Method.h"
#include "llvm/SymbolTable.h"
#include "llvm/Type.h"
+#include "llvm/CFG.h"
+#include "llvm/iOther.h"
// Instantiate Templates - This ugliness is the price we have to pay
// for having a ValueHolderImpl.h file seperate from ValueHolder.h! :(
@@ -79,6 +81,52 @@ bool BasicBlock::hasConstantPoolReferences() const {
return false;
}
+// removePredecessor - This method is used to notify a BasicBlock that the
+// specified Predecessor of the block is no longer able to reach it. This is
+// actually not used to update the Predecessor list, but is actually used to
+// update the PHI nodes that reside in the block. Note that this should be
+// called while the predecessor still refers to this block.
+//
+void BasicBlock::removePredecessor(BasicBlock *Pred) {
+ using cfg::pred_begin; using cfg::pred_end; using cfg::pred_iterator;
+ assert(find(pred_begin(this), pred_end(this), Pred) != pred_end(this) &&
+ "removePredecessor: BB is not a predecessor!");
+ if (!front()->isPHINode()) return; // Quick exit.
+
+ pred_iterator PI(pred_begin(this)), EI(pred_end(this));
+ unsigned max_idx;
+
+ // Loop over the rest of the predecessors until we run out, or until we find
+ // out that there are more than 2 predecessors.
+ for (max_idx = 0; PI != EI && max_idx < 3; ++PI, ++max_idx) /*empty*/;
+
+ // If there are exactly two predecessors, then we want to nuke the PHI nodes
+ // altogether.
+ assert(max_idx != 0 && "PHI Node in block with 0 predecessors!?!?!");
+ if (max_idx <= 2) { // <= Two predecessors BEFORE I remove one?
+ while (front()->isPHINode()) { // Yup, loop through and nuke the PHI nodes
+ PHINode *PN = (PHINode*)front();
+ PN->removeIncomingValue(Pred); // Remove the predecessor first...
+
+ assert(PN->getNumIncomingValues() == max_idx-1 &&
+ "PHI node shouldn't have this many values!!!");
+
+ // If the PHI _HAD_ two uses, replace PHI node with its now *single* value
+ if (max_idx == 2)
+ PN->replaceAllUsesWith(PN->getOperand(0));
+ delete getInstList().remove(begin()); // Remove the PHI node
+ }
+ } else {
+ // Okay, now we know that we need to remove predecessor #pred_idx from all
+ // PHI nodes. Iterate over each PHI node fixing them up
+ iterator II(begin());
+ for (; (*II)->isPHINode(); ++II) {
+ PHINode *PN = (PHINode*)*II;
+ PN->removeIncomingValue(Pred);
+ }
+ }
+}
+
// splitBasicBlock - This splits a basic block into two at the specified
// instruction. Note that all instructions BEFORE the specified iterator stay