/// Everything before \p SplitPt stays in \p Old and everything starting with \p
/// SplitPt moves to a new block. The two blocks are joined by an unconditional
/// branch. The new block with name \p BBName is returned.
+///
+/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
+BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT,
+ LoopInfo *LI = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr,
+ const Twine &BBName = "", bool Before = false);
+
+/// Split the specified block at the specified instruction.
+///
+/// If \p Before is true, splitBlockBefore handles the block
+/// splitting. Otherwise, execution proceeds as described below.
+///
+/// Everything before \p SplitPt stays in \p Old and everything starting with \p
+/// SplitPt moves to a new block. The two blocks are joined by an unconditional
+/// branch. The new block with name \p BBName is returned.
BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt,
- DominatorTree *DT = nullptr, LoopInfo *LI = nullptr,
+ DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
MemorySSAUpdater *MSSAU = nullptr,
const Twine &BBName = "", bool Before = false);
for (BasicBlock *Succ : successors(Check0))
DTUpdates.push_back({DT->Delete, Check0, Succ});
- BasicBlock *Check1 = SplitBlock(MatMul->getParent(), MatMul, nullptr, LI,
- nullptr, "alias_cont");
+ BasicBlock *Check1 =
+ SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
+ nullptr, "alias_cont");
BasicBlock *Copy =
- SplitBlock(MatMul->getParent(), MatMul, nullptr, LI, nullptr, "copy");
- BasicBlock *Fusion = SplitBlock(MatMul->getParent(), MatMul, nullptr, LI,
- nullptr, "no_alias");
+ SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
+ nullptr, "copy");
+ BasicBlock *Fusion =
+ SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
+ nullptr, "no_alias");
// Check if the loaded memory location begins before the end of the store
// location. If the condition holds, they might overlap, otherwise they are
return NumBroken;
}
-BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
- DominatorTree *DT, LoopInfo *LI,
- MemorySSAUpdater *MSSAU, const Twine &BBName,
- bool Before) {
+static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
+ DomTreeUpdater *DTU, DominatorTree *DT,
+ LoopInfo *LI, MemorySSAUpdater *MSSAU,
+ const Twine &BBName, bool Before) {
if (Before) {
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
- return splitBlockBefore(Old, SplitPt, &DTU, LI, MSSAU, BBName);
+ DomTreeUpdater LocalDTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+ return splitBlockBefore(Old, SplitPt,
+ DTU ? DTU : (DT ? &LocalDTU : nullptr), LI, MSSAU,
+ BBName);
}
BasicBlock::iterator SplitIt = SplitPt->getIterator();
while (isa<PHINode>(SplitIt) || SplitIt->isEHPad())
if (Loop *L = LI->getLoopFor(Old))
L->addBasicBlockToLoop(New, *LI);
- if (DT)
+ 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));
+ Updates.push_back({DominatorTree::Insert, Old, New});
+ Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfOld.size());
+ for (BasicBlock *UniqueSuccessorOfOld : UniqueSuccessorsOfOld) {
+ Updates.push_back({DominatorTree::Insert, New, UniqueSuccessorOfOld});
+ Updates.push_back({DominatorTree::Delete, Old, UniqueSuccessorOfOld});
+ }
+
+ DTU->applyUpdates(Updates);
+ } else if (DT)
// Old dominates New. New node dominates all other nodes dominated by Old.
if (DomTreeNode *OldNode = DT->getNode(Old)) {
std::vector<DomTreeNode *> Children(OldNode->begin(), OldNode->end());
return New;
}
+BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
+ DominatorTree *DT, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU, const Twine &BBName,
+ bool Before) {
+ return SplitBlockImpl(Old, SplitPt, /*DTU=*/nullptr, DT, LI, MSSAU, BBName,
+ Before);
+}
+BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
+ DomTreeUpdater *DTU, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU, const Twine &BBName,
+ bool Before) {
+ return SplitBlockImpl(Old, SplitPt, DTU, /*DT=*/nullptr, LI, MSSAU, BBName,
+ Before);
+}
+
BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
DomTreeUpdater *DTU, LoopInfo *LI,
MemorySSAUpdater *MSSAU,
// then we evaluate them with an explicit branch first. Split the block
// right before the condbr to handle it.
if (ExtraCase) {
- BasicBlock *NewBB =
- SplitBlock(BB, BI, DTU ? &DTU->getDomTree() : nullptr, /*LI=*/nullptr,
- /*MSSAU=*/nullptr, "switch.early.test");
+ BasicBlock *NewBB = SplitBlock(BB, BI, DTU, /*LI=*/nullptr,
+ /*MSSAU=*/nullptr, "switch.early.test");
// Remove the uncond branch added to the old block.
Instruction *OldTI = BB->getTerminator();
if (DTU)
DTU->applyUpdates({{DominatorTree::Insert, BB, &*NewDefaultBlock},
{DominatorTree::Delete, BB, OrigDefaultBlock}});
- SplitBlock(&*NewDefaultBlock, &NewDefaultBlock->front(),
- DTU ? &DTU->getDomTree() : nullptr);
+ SplitBlock(&*NewDefaultBlock, &NewDefaultBlock->front(), DTU);
SmallVector<DominatorTree::UpdateType, 2> Updates;
for (auto *Successor : successors(NewDefaultBlock))
Updates.push_back({DominatorTree::Delete, NewDefaultBlock, Successor});