diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index 68d1fd892402c..6472e1771ec73 100644 --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -1054,50 +1054,6 @@ BasicBlock *llvm::SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, return SplitBlockImpl(Old, SplitPt, DTU, /*DT=*/nullptr, LI, MSSAU, BBName); } -BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, BasicBlock::iterator SplitPt, - DomTreeUpdater *DTU, LoopInfo *LI, - MemorySSAUpdater *MSSAU, - const Twine &BBName) { - - BasicBlock::iterator SplitIt = SplitPt; - while (isa(SplitIt) || SplitIt->isEHPad()) - ++SplitIt; - std::string Name = BBName.str(); - BasicBlock *New = Old->splitBasicBlockBefore( - SplitIt, Name.empty() ? Old->getName() + ".split" : Name); - - // The new block lives in whichever loop the old one did. This preserves - // LCSSA as well, because we force the split point to be after any PHI nodes. - if (LI) - if (Loop *L = LI->getLoopFor(Old)) - L->addBasicBlockToLoop(New, *LI); - - if (DTU) { - SmallVector DTUpdates; - // New dominates Old. The predecessor nodes of the Old node dominate - // New node. - SmallPtrSet UniquePredecessorsOfOld; - DTUpdates.push_back({DominatorTree::Insert, New, Old}); - DTUpdates.reserve(DTUpdates.size() + 2 * pred_size(New)); - for (BasicBlock *PredecessorOfOld : predecessors(New)) - if (UniquePredecessorsOfOld.insert(PredecessorOfOld).second) { - DTUpdates.push_back({DominatorTree::Insert, PredecessorOfOld, New}); - DTUpdates.push_back({DominatorTree::Delete, PredecessorOfOld, Old}); - } - - DTU->applyUpdates(DTUpdates); - - // Move MemoryAccesses still tracked in Old, but part of New now. - // Update accesses in successor blocks accordingly. - if (MSSAU) { - MSSAU->applyUpdates(DTUpdates, DTU->getDomTree()); - if (VerifyMemorySSA) - MSSAU->getMemorySSA()->verifyMemorySSA(); - } - } - return New; -} - /// Update DominatorTree, LoopInfo, and LCCSA analysis information. /// Invalidates DFS Numbering when DTU or DT is provided. static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB, @@ -1212,6 +1168,25 @@ static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB, } } +BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, + BasicBlock::iterator SplitPt, + DomTreeUpdater *DTU, LoopInfo *LI, + MemorySSAUpdater *MSSAU, + const Twine &BBName) { + BasicBlock::iterator SplitIt = SplitPt; + while (isa(SplitIt) || SplitIt->isEHPad()) + ++SplitIt; + SmallVector Preds(predecessors(Old)); + BasicBlock *New = Old->splitBasicBlockBefore( + SplitIt, BBName.isTriviallyEmpty() ? Old->getName() + ".split" : BBName); + + bool HasLoopExit = false; + UpdateAnalysisInformation(Old, New, Preds, DTU, nullptr, LI, MSSAU, false, + HasLoopExit); + + return New; +} + /// Update the PHI nodes in OrigBB to include the values coming from NewBB. /// This also updates AliasAnalysis, if available. static void UpdatePHINodes(BasicBlock *OrigBB, BasicBlock *NewBB, diff --git a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp index 00d9e9ff81e05..d5b4f6b6d6593 100644 --- a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp +++ b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp @@ -378,6 +378,31 @@ define i32 @no_unreachable(i1 %cond) { EXPECT_TRUE(DT.verify()); } +TEST(BasicBlockUtils, splitBlockBefore) { + LLVMContext C; + std::unique_ptr M = parseIR(C, R"IR( +define i32 @basic_func(i1 %cond) { +entry: + br i1 %cond, label %bb0, label %bb1 +bb0: + br label %bb1 +bb1: + %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ] + ret i32 %phi +} +)IR"); + Function *F = M->getFunction("basic_func"); + DominatorTree DT(*F); + DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); + BasicBlock *EntryBB = &F->getEntryBlock(); + Instruction *TI = EntryBB->getTerminator(); + + // Make sure the dominator tree is properly updated if calling this on the + // entry block. + splitBlockBefore(EntryBB, TI, &DTU, nullptr, nullptr); + EXPECT_TRUE(DTU.getDomTree().verify()); +} + TEST(BasicBlockUtils, SplitBlockPredecessors) { LLVMContext C; std::unique_ptr M = parseIR(C, R"IR(