return make_range<phi_iterator>(P, nullptr);
}
-/// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred.
-/// Note that this function does not actually remove the predecessor.
+/// 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,
bool KeepOneInputPHIs) {
- // Use hasNUsesOrMore to bound the cost of this assertion for complex CFGs.
- assert((hasNUsesOrMore(16) ||
+ assert((hasNUsesOrMore(16)||// Reduce cost of this assertion for complex CFGs.
find(pred_begin(this), pred_end(this), Pred) != pred_end(this)) &&
- "Pred is not a predecessor!");
+ "removePredecessor: BB is not a predecessor!");
+
+ if (InstList.empty()) return;
+ PHINode *APN = dyn_cast<PHINode>(&front());
+ if (!APN) return; // Quick exit.
+
+ // If there are exactly two predecessors, then we want to nuke the PHI nodes
+ // altogether.
+ unsigned max_idx = APN->getNumIncomingValues();
+ assert(max_idx != 0 && "PHI Node in block with 0 predecessors!?!?!");
+
+ // <= Two predecessors BEFORE I remove one?
+ if (max_idx <= 2 && !KeepOneInputPHIs) {
+ // Yup, loop through and nuke the PHI nodes
+ while (PHINode *PN = dyn_cast<PHINode>(&front())) {
+ // Remove the predecessor first.
+ PN->removeIncomingValue(Pred, !KeepOneInputPHIs);
+
+ // If the PHI _HAD_ two uses, replace PHI node with its now *single* value
+ if (max_idx == 2) {
+ if (PN->getIncomingValue(0) != PN)
+ PN->replaceAllUsesWith(PN->getIncomingValue(0));
+ else
+ // We are left with an infinite loop with no entries: kill the PHI.
+ PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
+ getInstList().pop_front(); // Remove the PHI node
+ }
- // Return early if there are no PHI nodes to update.
- if (!isa<PHINode>(begin()))
- return;
- unsigned NumPreds = cast<PHINode>(front()).getNumIncomingValues();
-
- // Update all PHI nodes.
- for (iterator II = begin(); isa<PHINode>(II);) {
- PHINode *PN = cast<PHINode>(II++);
- PN->removeIncomingValue(Pred);
- // If we have a single predecessor, removeIncomingValue erased the PHI node
- // itself.
- // FIXME in practice "KeepOneInputPHIs" means "KeepConstantPHIs" and some
- // callers seem to rely on that.
- if (NumPreds > 1 && !KeepOneInputPHIs) {
- if (Value *PNV = PN->hasConstantValue()) {
- // Replace the PHI node with its constant value.
+ // If the PHI node already only had one entry, it got deleted by
+ // removeIncomingValue.
+ }
+ } 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
+ PHINode *PN;
+ for (iterator II = begin(); (PN = dyn_cast<PHINode>(II)); ) {
+ ++II;
+ PN->removeIncomingValue(Pred, false);
+ // If all incoming values to the Phi are the same, we can replace the Phi
+ // with that value.
+ Value* PNV = nullptr;
+ if (!KeepOneInputPHIs && (PNV = PN->hasConstantValue())) {
PN->replaceAllUsesWith(PNV);
PN->eraseFromParent();
}