aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/Transforms/Utils/BasicBlockUtils.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/BasicBlockUtils.cpp328
1 files changed, 271 insertions, 57 deletions
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 6bcd42c4c6d8..ee933b638a23 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -33,6 +33,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/PseudoProbe.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -124,11 +125,9 @@ bool llvm::EliminateUnreachableBlocks(Function &F, DomTreeUpdater *DTU,
// Collect all dead blocks.
std::vector<BasicBlock*> DeadBlocks;
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
- if (!Reachable.count(&*I)) {
- BasicBlock *BB = &*I;
- DeadBlocks.push_back(BB);
- }
+ for (BasicBlock &BB : F)
+ if (!Reachable.count(&BB))
+ DeadBlocks.push_back(&BB);
// Delete the dead blocks.
DeleteDeadBlocks(DeadBlocks, DTU, KeepOneInputPHIs);
@@ -209,9 +208,8 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
// Can't merge if there is PHI loop.
for (PHINode &PN : BB->phis())
- for (Value *IncValue : PN.incoming_values())
- if (IncValue == &PN)
- return false;
+ if (llvm::is_contained(PN.incoming_values(), &PN))
+ return false;
LLVM_DEBUG(dbgs() << "Merging: " << BB->getName() << " into "
<< PredBB->getName() << "\n");
@@ -230,21 +228,22 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
// These dominator edges will be redirected from Pred.
std::vector<DominatorTree::UpdateType> Updates;
if (DTU) {
- SmallSetVector<BasicBlock *, 2> UniqueSuccessors(succ_begin(BB),
- succ_end(BB));
- Updates.reserve(1 + (2 * UniqueSuccessors.size()));
+ SmallPtrSet<BasicBlock *, 2> SuccsOfBB(succ_begin(BB), succ_end(BB));
+ SmallPtrSet<BasicBlock *, 2> SuccsOfPredBB(succ_begin(PredBB),
+ succ_begin(PredBB));
+ Updates.reserve(Updates.size() + 2 * SuccsOfBB.size() + 1);
// Add insert edges first. Experimentally, for the particular case of two
// blocks that can be merged, with a single successor and single predecessor
// respectively, it is beneficial to have all insert updates first. Deleting
// edges first may lead to unreachable blocks, followed by inserting edges
// making the blocks reachable again. Such DT updates lead to high compile
// times. We add inserts before deletes here to reduce compile time.
- for (BasicBlock *UniqueSuccessor : UniqueSuccessors)
- // This successor of BB may already have PredBB as a predecessor.
- if (!llvm::is_contained(successors(PredBB), UniqueSuccessor))
- Updates.push_back({DominatorTree::Insert, PredBB, UniqueSuccessor});
- for (BasicBlock *UniqueSuccessor : UniqueSuccessors)
- Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor});
+ for (BasicBlock *SuccOfBB : SuccsOfBB)
+ // This successor of BB may already be a PredBB's successor.
+ if (!SuccsOfPredBB.contains(SuccOfBB))
+ Updates.push_back({DominatorTree::Insert, PredBB, SuccOfBB});
+ for (BasicBlock *SuccOfBB : SuccsOfBB)
+ Updates.push_back({DominatorTree::Delete, BB, SuccOfBB});
Updates.push_back({DominatorTree::Delete, PredBB, BB});
}
@@ -299,17 +298,11 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
if (MemDep)
MemDep->invalidateCachedPredecessors();
- // Finally, erase the old block and update dominator info.
- if (DTU) {
- assert(BB->getInstList().size() == 1 &&
- isa<UnreachableInst>(BB->getTerminator()) &&
- "The successor list of BB isn't empty before "
- "applying corresponding DTU updates.");
+ if (DTU)
DTU->applyUpdates(Updates);
- DTU->deleteBB(BB);
- } else {
- BB->eraseFromParent(); // Nuke BB if DTU is nullptr.
- }
+
+ // Finally, erase the old block and update dominator info.
+ DeleteDeadBlock(BB, DTU);
return true;
}
@@ -409,7 +402,8 @@ static bool removeRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) {
/// - Keep track of non-overlapping fragments.
static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) {
SmallVector<DbgValueInst *, 8> ToBeRemoved;
- DenseMap<DebugVariable, std::pair<Value *, DIExpression *> > VariableMap;
+ DenseMap<DebugVariable, std::pair<SmallVector<Value *, 4>, DIExpression *>>
+ VariableMap;
for (auto &I : *BB) {
if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(&I)) {
DebugVariable Key(DVI->getVariable(),
@@ -418,10 +412,10 @@ static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) {
auto VMI = VariableMap.find(Key);
// Update the map if we found a new value/expression describing the
// variable, or if the variable wasn't mapped already.
- if (VMI == VariableMap.end() ||
- VMI->second.first != DVI->getValue() ||
+ SmallVector<Value *, 4> Values(DVI->getValues());
+ if (VMI == VariableMap.end() || VMI->second.first != Values ||
VMI->second.second != DVI->getExpression()) {
- VariableMap[Key] = { DVI->getValue(), DVI->getExpression() };
+ VariableMap[Key] = {Values, DVI->getExpression()};
continue;
}
// Found an identical mapping. Remember the instruction for later removal.
@@ -501,13 +495,20 @@ BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, DominatorTree *DT,
const Twine &BBName) {
unsigned SuccNum = GetSuccessorNumber(BB, Succ);
- // If this is a critical edge, let SplitCriticalEdge do it.
Instruction *LatchTerm = BB->getTerminator();
- if (SplitCriticalEdge(
- LatchTerm, SuccNum,
- CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA(),
- BBName))
- return LatchTerm->getSuccessor(SuccNum);
+
+ CriticalEdgeSplittingOptions Options =
+ CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA();
+
+ if ((isCriticalEdge(LatchTerm, SuccNum, Options.MergeIdenticalEdges))) {
+ // If it is a critical edge, and the succesor is an exception block, handle
+ // the split edge logic in this specific function
+ if (Succ->isEHPad())
+ return ehAwareSplitEdge(BB, Succ, nullptr, nullptr, Options, BBName);
+
+ // If this is a critical edge, let SplitKnownCriticalEdge do it.
+ return SplitKnownCriticalEdge(LatchTerm, SuccNum, Options, BBName);
+ }
// If the edge isn't critical, then BB has a single successor or Succ has a
// single pred. Split the block.
@@ -527,6 +528,218 @@ BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, DominatorTree *DT,
return SplitBlock(BB, BB->getTerminator(), DT, LI, MSSAU, BBName);
}
+void llvm::setUnwindEdgeTo(Instruction *TI, BasicBlock *Succ) {
+ if (auto *II = dyn_cast<InvokeInst>(TI))
+ II->setUnwindDest(Succ);
+ else if (auto *CS = dyn_cast<CatchSwitchInst>(TI))
+ CS->setUnwindDest(Succ);
+ else if (auto *CR = dyn_cast<CleanupReturnInst>(TI))
+ CR->setUnwindDest(Succ);
+ else
+ llvm_unreachable("unexpected terminator instruction");
+}
+
+void llvm::updatePhiNodes(BasicBlock *DestBB, BasicBlock *OldPred,
+ BasicBlock *NewPred, PHINode *Until) {
+ int BBIdx = 0;
+ for (PHINode &PN : DestBB->phis()) {
+ // We manually update the LandingPadReplacement PHINode and it is the last
+ // PHI Node. So, if we find it, we are done.
+ if (Until == &PN)
+ break;
+
+ // Reuse the previous value of BBIdx if it lines up. In cases where we
+ // have multiple phi nodes with *lots* of predecessors, this is a speed
+ // win because we don't have to scan the PHI looking for TIBB. This
+ // happens because the BB list of PHI nodes are usually in the same
+ // order.
+ if (PN.getIncomingBlock(BBIdx) != OldPred)
+ BBIdx = PN.getBasicBlockIndex(OldPred);
+
+ assert(BBIdx != -1 && "Invalid PHI Index!");
+ PN.setIncomingBlock(BBIdx, NewPred);
+ }
+}
+
+BasicBlock *llvm::ehAwareSplitEdge(BasicBlock *BB, BasicBlock *Succ,
+ LandingPadInst *OriginalPad,
+ PHINode *LandingPadReplacement,
+ const CriticalEdgeSplittingOptions &Options,
+ const Twine &BBName) {
+
+ auto *PadInst = Succ->getFirstNonPHI();
+ if (!LandingPadReplacement && !PadInst->isEHPad())
+ return SplitEdge(BB, Succ, Options.DT, Options.LI, Options.MSSAU, BBName);
+
+ auto *LI = Options.LI;
+ SmallVector<BasicBlock *, 4> LoopPreds;
+ // Check if extra modifications will be required to preserve loop-simplify
+ // form after splitting. If it would require splitting blocks with IndirectBr
+ // terminators, bail out if preserving loop-simplify form is requested.
+ if (Options.PreserveLoopSimplify && LI) {
+ if (Loop *BBLoop = LI->getLoopFor(BB)) {
+
+ // The only way that we can break LoopSimplify form by splitting a
+ // critical edge is when there exists some edge from BBLoop to Succ *and*
+ // the only edge into Succ from outside of BBLoop is that of NewBB after
+ // the split. If the first isn't true, then LoopSimplify still holds,
+ // NewBB is the new exit block and it has no non-loop predecessors. If the
+ // second isn't true, then Succ was not in LoopSimplify form prior to
+ // the split as it had a non-loop predecessor. In both of these cases,
+ // the predecessor must be directly in BBLoop, not in a subloop, or again
+ // LoopSimplify doesn't hold.
+ for (BasicBlock *P : predecessors(Succ)) {
+ if (P == BB)
+ continue; // The new block is known.
+ if (LI->getLoopFor(P) != BBLoop) {
+ // Loop is not in LoopSimplify form, no need to re simplify after
+ // splitting edge.
+ LoopPreds.clear();
+ break;
+ }
+ LoopPreds.push_back(P);
+ }
+ // Loop-simplify form can be preserved, if we can split all in-loop
+ // predecessors.
+ if (any_of(LoopPreds, [](BasicBlock *Pred) {
+ return isa<IndirectBrInst>(Pred->getTerminator());
+ })) {
+ return nullptr;
+ }
+ }
+ }
+
+ auto *NewBB =
+ BasicBlock::Create(BB->getContext(), BBName, BB->getParent(), Succ);
+ setUnwindEdgeTo(BB->getTerminator(), NewBB);
+ updatePhiNodes(Succ, BB, NewBB, LandingPadReplacement);
+
+ if (LandingPadReplacement) {
+ auto *NewLP = OriginalPad->clone();
+ auto *Terminator = BranchInst::Create(Succ, NewBB);
+ NewLP->insertBefore(Terminator);
+ LandingPadReplacement->addIncoming(NewLP, NewBB);
+ } else {
+ Value *ParentPad = nullptr;
+ if (auto *FuncletPad = dyn_cast<FuncletPadInst>(PadInst))
+ ParentPad = FuncletPad->getParentPad();
+ else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(PadInst))
+ ParentPad = CatchSwitch->getParentPad();
+ else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(PadInst))
+ ParentPad = CleanupPad->getParentPad();
+ else if (auto *LandingPad = dyn_cast<LandingPadInst>(PadInst))
+ ParentPad = LandingPad->getParent();
+ else
+ llvm_unreachable("handling for other EHPads not implemented yet");
+
+ auto *NewCleanupPad = CleanupPadInst::Create(ParentPad, {}, BBName, NewBB);
+ CleanupReturnInst::Create(NewCleanupPad, Succ, NewBB);
+ }
+
+ auto *DT = Options.DT;
+ auto *MSSAU = Options.MSSAU;
+ if (!DT && !LI)
+ return NewBB;
+
+ if (DT) {
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+ SmallVector<DominatorTree::UpdateType, 3> Updates;
+
+ Updates.push_back({DominatorTree::Insert, BB, NewBB});
+ Updates.push_back({DominatorTree::Insert, NewBB, Succ});
+ Updates.push_back({DominatorTree::Delete, BB, Succ});
+
+ DTU.applyUpdates(Updates);
+ DTU.flush();
+
+ if (MSSAU) {
+ MSSAU->applyUpdates(Updates, *DT);
+ if (VerifyMemorySSA)
+ MSSAU->getMemorySSA()->verifyMemorySSA();
+ }
+ }
+
+ if (LI) {
+ if (Loop *BBLoop = LI->getLoopFor(BB)) {
+ // If one or the other blocks were not in a loop, the new block is not
+ // either, and thus LI doesn't need to be updated.
+ if (Loop *SuccLoop = LI->getLoopFor(Succ)) {
+ if (BBLoop == SuccLoop) {
+ // Both in the same loop, the NewBB joins loop.
+ SuccLoop->addBasicBlockToLoop(NewBB, *LI);
+ } else if (BBLoop->contains(SuccLoop)) {
+ // Edge from an outer loop to an inner loop. Add to the outer loop.
+ BBLoop->addBasicBlockToLoop(NewBB, *LI);
+ } else if (SuccLoop->contains(BBLoop)) {
+ // Edge from an inner loop to an outer loop. Add to the outer loop.
+ SuccLoop->addBasicBlockToLoop(NewBB, *LI);
+ } else {
+ // Edge from two loops with no containment relation. Because these
+ // are natural loops, we know that the destination block must be the
+ // header of its loop (adding a branch into a loop elsewhere would
+ // create an irreducible loop).
+ assert(SuccLoop->getHeader() == Succ &&
+ "Should not create irreducible loops!");
+ if (Loop *P = SuccLoop->getParentLoop())
+ P->addBasicBlockToLoop(NewBB, *LI);
+ }
+ }
+
+ // If BB is in a loop and Succ is outside of that loop, we may need to
+ // update LoopSimplify form and LCSSA form.
+ if (!BBLoop->contains(Succ)) {
+ assert(!BBLoop->contains(NewBB) &&
+ "Split point for loop exit is contained in loop!");
+
+ // Update LCSSA form in the newly created exit block.
+ if (Options.PreserveLCSSA) {
+ createPHIsForSplitLoopExit(BB, NewBB, Succ);
+ }
+
+ if (!LoopPreds.empty()) {
+ BasicBlock *NewExitBB = SplitBlockPredecessors(
+ Succ, LoopPreds, "split", DT, LI, MSSAU, Options.PreserveLCSSA);
+ if (Options.PreserveLCSSA)
+ createPHIsForSplitLoopExit(LoopPreds, NewExitBB, Succ);
+ }
+ }
+ }
+ }
+
+ return NewBB;
+}
+
+void llvm::createPHIsForSplitLoopExit(ArrayRef<BasicBlock *> Preds,
+ BasicBlock *SplitBB, BasicBlock *DestBB) {
+ // SplitBB shouldn't have anything non-trivial in it yet.
+ assert((SplitBB->getFirstNonPHI() == SplitBB->getTerminator() ||
+ SplitBB->isLandingPad()) &&
+ "SplitBB has non-PHI nodes!");
+
+ // For each PHI in the destination block.
+ for (PHINode &PN : DestBB->phis()) {
+ int Idx = PN.getBasicBlockIndex(SplitBB);
+ assert(Idx >= 0 && "Invalid Block Index");
+ Value *V = PN.getIncomingValue(Idx);
+
+ // If the input is a PHI which already satisfies LCSSA, don't create
+ // a new one.
+ if (const PHINode *VP = dyn_cast<PHINode>(V))
+ if (VP->getParent() == SplitBB)
+ continue;
+
+ // Otherwise a new PHI is needed. Create one and populate it.
+ PHINode *NewPN = PHINode::Create(
+ PN.getType(), Preds.size(), "split",
+ SplitBB->isLandingPad() ? &SplitBB->front() : SplitBB->getTerminator());
+ for (BasicBlock *BB : Preds)
+ NewPN->addIncoming(V, BB);
+
+ // Update the original PHI.
+ PN.setIncomingValue(Idx, NewPN);
+ }
+}
+
unsigned
llvm::SplitAllCriticalEdges(Function &F,
const CriticalEdgeSplittingOptions &Options) {
@@ -553,8 +766,10 @@ static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
BBName);
}
BasicBlock::iterator SplitIt = SplitPt->getIterator();
- while (isa<PHINode>(SplitIt) || SplitIt->isEHPad())
+ while (isa<PHINode>(SplitIt) || SplitIt->isEHPad()) {
++SplitIt;
+ assert(SplitIt != SplitPt->getParent()->end());
+ }
std::string Name = BBName.str();
BasicBlock *New = Old->splitBasicBlock(
SplitIt, Name.empty() ? Old->getName() + ".split" : Name);
@@ -568,8 +783,8 @@ static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
if (DTU) {
SmallVector<DominatorTree::UpdateType, 8> Updates;
// Old dominates New. New node dominates all other nodes dominated by Old.
- SmallSetVector<BasicBlock *, 8> UniqueSuccessorsOfOld(succ_begin(New),
- succ_end(New));
+ SmallPtrSet<BasicBlock *, 8> UniqueSuccessorsOfOld(succ_begin(New),
+ succ_end(New));
Updates.push_back({DominatorTree::Insert, Old, New});
Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfOld.size());
for (BasicBlock *UniqueSuccessorOfOld : UniqueSuccessorsOfOld) {
@@ -634,8 +849,8 @@ BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
SmallVector<DominatorTree::UpdateType, 8> DTUpdates;
// New dominates Old. The predecessor nodes of the Old node dominate
// New node.
- SmallSetVector<BasicBlock *, 8> UniquePredecessorsOfOld(pred_begin(New),
- pred_end(New));
+ SmallPtrSet<BasicBlock *, 8> UniquePredecessorsOfOld(pred_begin(New),
+ pred_end(New));
DTUpdates.push_back({DominatorTree::Insert, New, Old});
DTUpdates.reserve(DTUpdates.size() + 2 * UniquePredecessorsOfOld.size());
for (BasicBlock *UniquePredecessorOfOld : UniquePredecessorsOfOld) {
@@ -666,7 +881,7 @@ static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB,
if (DTU) {
// Recalculation of DomTree is needed when updating a forward DomTree and
// the Entry BB is replaced.
- if (NewBB == &NewBB->getParent()->getEntryBlock() && DTU->hasDomTree()) {
+ if (NewBB->isEntryBlock() && DTU->hasDomTree()) {
// The entry block was removed and there is no external interface for
// the dominator tree to be notified of this change. In this corner-case
// we recalculate the entire tree.
@@ -674,7 +889,7 @@ static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB,
} else {
// Split block expects NewBB to have a non-empty set of predecessors.
SmallVector<DominatorTree::UpdateType, 8> Updates;
- SmallSetVector<BasicBlock *, 8> UniquePreds(Preds.begin(), Preds.end());
+ SmallPtrSet<BasicBlock *, 8> UniquePreds(Preds.begin(), Preds.end());
Updates.push_back({DominatorTree::Insert, NewBB, OldBB});
Updates.reserve(Updates.size() + 2 * UniquePreds.size());
for (auto *UniquePred : UniquePreds) {
@@ -685,7 +900,7 @@ static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB,
}
} else if (DT) {
if (OldBB == DT->getRootNode()->getBlock()) {
- assert(NewBB == &NewBB->getParent()->getEntryBlock());
+ assert(NewBB->isEntryBlock());
DT->setNewRoot(NewBB);
} else {
// Split block expects NewBB to have a non-empty set of predecessors.
@@ -1083,9 +1298,8 @@ ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
// If the return instruction returns a value, and if the value was a
// PHI node in "BB", propagate the right value into the return.
- for (User::op_iterator i = NewRet->op_begin(), e = NewRet->op_end();
- i != e; ++i) {
- Value *V = *i;
+ for (Use &Op : NewRet->operands()) {
+ Value *V = Op;
Instruction *NewBC = nullptr;
if (BitCastInst *BCI = dyn_cast<BitCastInst>(V)) {
// Return value might be bitcasted. Clone and insert it before the
@@ -1093,7 +1307,7 @@ ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
V = BCI->getOperand(0);
NewBC = BCI->clone();
Pred->getInstList().insert(NewRet->getIterator(), NewBC);
- *i = NewBC;
+ Op = NewBC;
}
Instruction *NewEV = nullptr;
@@ -1105,7 +1319,7 @@ ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
Pred->getInstList().insert(NewBC->getIterator(), NewEV);
} else {
Pred->getInstList().insert(NewRet->getIterator(), NewEV);
- *i = NewEV;
+ Op = NewEV;
}
}
@@ -1116,7 +1330,7 @@ ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
} else if (NewBC)
NewBC->setOperand(0, PN->getIncomingValueForBlock(Pred));
else
- *i = PN->getIncomingValueForBlock(Pred);
+ Op = PN->getIncomingValueForBlock(Pred);
}
}
}
@@ -1141,8 +1355,8 @@ SplitBlockAndInsertIfThenImpl(Value *Cond, Instruction *SplitBefore,
BasicBlock *Head = SplitBefore->getParent();
BasicBlock *Tail = Head->splitBasicBlock(SplitBefore->getIterator());
if (DTU) {
- SmallSetVector<BasicBlock *, 8> UniqueSuccessorsOfHead(succ_begin(Tail),
- succ_end(Tail));
+ SmallPtrSet<BasicBlock *, 8> UniqueSuccessorsOfHead(succ_begin(Tail),
+ succ_end(Tail));
Updates.push_back({DominatorTree::Insert, Head, Tail});
Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfHead.size());
for (BasicBlock *UniqueSuccessorOfHead : UniqueSuccessorsOfHead) {
@@ -1242,8 +1456,8 @@ void llvm::SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
ReplaceInstWithInst(HeadOldTerm, HeadNewTerm);
}
-Value *llvm::GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
- BasicBlock *&IfFalse) {
+BranchInst *llvm::GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
+ BasicBlock *&IfFalse) {
PHINode *SomePHI = dyn_cast<PHINode>(BB->begin());
BasicBlock *Pred1 = nullptr;
BasicBlock *Pred2 = nullptr;
@@ -1309,7 +1523,7 @@ Value *llvm::GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
return nullptr;
}
- return Pred1Br->getCondition();
+ return Pred1Br;
}
// Ok, if we got here, both predecessors end with an unconditional branch to
@@ -1331,7 +1545,7 @@ Value *llvm::GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
IfTrue = Pred2;
IfFalse = Pred1;
}
- return BI->getCondition();
+ return BI;
}
// After creating a control flow hub, the operands of PHINodes in an outgoing