Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/CodeGenPrepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6868,7 +6868,8 @@ bool CodeGenPrepare::splitLargeGEPOffsets() {
NewBaseInsertPt = NewBaseInsertBB->getFirstInsertionPt();
else if (InvokeInst *Invoke = dyn_cast<InvokeInst>(BaseI)) {
NewBaseInsertBB =
SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI);
SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(),
&getDT(*NewBaseInsertBB->getParent()), LI);
NewBaseInsertPt = NewBaseInsertBB->getFirstInsertionPt();
} else
NewBaseInsertPt = std::next(BaseI->getIterator());
Expand Down
63 changes: 19 additions & 44 deletions llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<PHINode>(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<DominatorTree::UpdateType, 8> DTUpdates;
// New dominates Old. The predecessor nodes of the Old node dominate
// New node.
SmallPtrSet<BasicBlock *, 8> 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,
Expand Down Expand Up @@ -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<PHINode>(SplitIt) || SplitIt->isEHPad())
++SplitIt;
SmallVector<BasicBlock *, 4> 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,
Expand Down
25 changes: 25 additions & 0 deletions llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,31 @@ define i32 @no_unreachable(i1 %cond) {
EXPECT_TRUE(DT.verify());
}

TEST(BasicBlockUtils, splitBlockBefore) {
LLVMContext C;
std::unique_ptr<Module> 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<Module> M = parseIR(C, R"IR(
Expand Down