forked from OSchip/llvm-project
[IR] Simplify BasicBlock::removePredecessor. NFCI.
Differential Revision: https://reviews.llvm.org/D80141
This commit is contained in:
parent
0d736f467d
commit
59f49f7ee7
|
@ -370,12 +370,8 @@ public:
|
|||
/// except operator delete.
|
||||
void dropAllReferences();
|
||||
|
||||
/// Notify the BasicBlock that the predecessor \p Pred 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.
|
||||
/// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred.
|
||||
/// Note that this function does not actually remove the predecessor.
|
||||
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false);
|
||||
|
||||
bool canSplitPredecessors() const;
|
||||
|
|
|
@ -317,58 +317,31 @@ iterator_range<BasicBlock::phi_iterator> BasicBlock::phis() {
|
|||
return make_range<phi_iterator>(P, nullptr);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred.
|
||||
/// Note that this function does not actually remove the predecessor.
|
||||
void BasicBlock::removePredecessor(BasicBlock *Pred,
|
||||
bool KeepOneInputPHIs) {
|
||||
assert((hasNUsesOrMore(16)||// Reduce cost of this assertion for complex CFGs.
|
||||
// Use hasNUsesOrMore to bound the cost of this assertion for complex CFGs.
|
||||
assert((hasNUsesOrMore(16) ||
|
||||
find(pred_begin(this), pred_end(this), Pred) != pred_end(this)) &&
|
||||
"removePredecessor: BB is not a predecessor!");
|
||||
"Pred is not a predecessor!");
|
||||
|
||||
if (InstList.empty()) return;
|
||||
PHINode *APN = dyn_cast<PHINode>(&front());
|
||||
if (!APN) return; // Quick exit.
|
||||
// Return early if there are no PHI nodes to update.
|
||||
if (!isa<PHINode>(begin()))
|
||||
return;
|
||||
unsigned NumPreds = cast<PHINode>(front()).getNumIncomingValues();
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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())) {
|
||||
// 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.
|
||||
PN->replaceAllUsesWith(PNV);
|
||||
PN->eraseFromParent();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue