diff options
author | Jay Foad <jay.foad@amd.com> | 2020-05-20 08:01:43 +0100 |
---|---|---|
committer | Jay Foad <jay.foad@amd.com> | 2020-05-20 08:01:43 +0100 |
commit | b42b30c335bccccca95470aa47dade2e25cb8994 (patch) | |
tree | e9ac003bb7eb0661a19dd26230a87cc2ab640195 /llvm/lib/IR/BasicBlock.cpp | |
parent | 807ab2cd0db398c420ca5b8a7fc260aaea5051a1 (diff) | |
download | llvm-b42b30c335bccccca95470aa47dade2e25cb8994.zip llvm-b42b30c335bccccca95470aa47dade2e25cb8994.tar.gz llvm-b42b30c335bccccca95470aa47dade2e25cb8994.tar.bz2 |
Revert "[IR] Simplify BasicBlock::removePredecessor. NFCI."
This reverts commit 59f49f7ee7f3397e000f7e11facb4a5605cd1cab.
It was causing buildbot failures.
Diffstat (limited to 'llvm/lib/IR/BasicBlock.cpp')
-rw-r--r-- | llvm/lib/IR/BasicBlock.cpp | 69 |
1 files changed, 48 insertions, 21 deletions
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index fb4639c..a9fa7cae 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -317,31 +317,58 @@ iterator_range<BasicBlock::phi_iterator> BasicBlock::phis() { 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(); } |