Skip to content

Commit cf638d7

Browse files
bangtianliuWhitney Tsang
authored andcommitted
Ensure SplitEdge to return the new block between the two given blocks
This PR implements the function splitBasicBlockBefore to address an issue that occurred during SplitEdge(BB, Succ, ...), inside splitBlockBefore. The issue occurs in SplitEdge when the Succ has a single predecessor and the edge between the BB and Succ is not critical. This produces the result ‘BB->Succ->New’. The new function splitBasicBlockBefore was added to splitBlockBefore to handle the issue and now produces the correct result ‘BB->New->Succ’. Below is an example of splitting the block bb1 at its first instruction. /// Original IR bb0: br bb1 bb1: %0 = mul i32 1, 2 br bb2 bb2: /// IR after splitEdge(bb0, bb1) using splitBasicBlock bb0: br bb1 bb1: br bb1.split bb1.split: %0 = mul i32 1, 2 br bb2 bb2: /// IR after splitEdge(bb0, bb1) using splitBasicBlockBefore bb0: br bb1.split bb1.split br bb1 bb1: %0 = mul i32 1, 2 br bb2 bb2: Differential Revision: https://reviews.llvm.org/D92200
1 parent 0dd8f6f commit cf638d7

File tree

7 files changed

+383
-28
lines changed

7 files changed

+383
-28
lines changed

llvm/include/llvm/IR/BasicBlock.h

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -396,22 +396,49 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
396396

397397
/// Split the basic block into two basic blocks at the specified instruction.
398398
///
399-
/// Note that all instructions BEFORE the specified iterator stay as part of
400-
/// the original basic block, an unconditional branch is added to the original
401-
/// BB, and the rest of the instructions in the BB are moved to the new BB,
402-
/// including the old terminator. The newly formed BasicBlock is returned.
403-
/// This function invalidates the specified iterator.
399+
/// If \p Before is true, splitBasicBlockBefore handles the
400+
/// block splitting. Otherwise, execution proceeds as described below.
401+
///
402+
/// Note that all instructions BEFORE the specified iterator
403+
/// stay as part of the original basic block, an unconditional branch is added
404+
/// to the original BB, and the rest of the instructions in the BB are moved
405+
/// to the new BB, including the old terminator. The newly formed basic block
406+
/// is returned. This function invalidates the specified iterator.
404407
///
405408
/// Note that this only works on well formed basic blocks (must have a
406-
/// terminator), and 'I' must not be the end of instruction list (which would
407-
/// cause a degenerate basic block to be formed, having a terminator inside of
408-
/// the basic block).
409+
/// terminator), and \p 'I' must not be the end of instruction list (which
410+
/// would cause a degenerate basic block to be formed, having a terminator
411+
/// inside of the basic block).
409412
///
410413
/// Also note that this doesn't preserve any passes. To split blocks while
411414
/// keeping loop information consistent, use the SplitBlock utility function.
412-
BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "");
413-
BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "") {
414-
return splitBasicBlock(I->getIterator(), BBName);
415+
BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "",
416+
bool Before = false);
417+
BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "",
418+
bool Before = false) {
419+
return splitBasicBlock(I->getIterator(), BBName, Before);
420+
}
421+
422+
/// Split the basic block into two basic blocks at the specified instruction
423+
/// and insert the new basic blocks as the predecessor of the current block.
424+
///
425+
/// This function ensures all instructions AFTER and including the specified
426+
/// iterator \p I are part of the original basic block. All Instructions
427+
/// BEFORE the iterator \p I are moved to the new BB and an unconditional
428+
/// branch is added to the new BB. The new basic block is returned.
429+
///
430+
/// Note that this only works on well formed basic blocks (must have a
431+
/// terminator), and \p 'I' must not be the end of instruction list (which
432+
/// would cause a degenerate basic block to be formed, having a terminator
433+
/// inside of the basic block). \p 'I' cannot be a iterator for a PHINode
434+
/// with multiple incoming blocks.
435+
///
436+
/// Also note that this doesn't preserve any passes. To split blocks while
437+
/// keeping loop information consistent, use the SplitBlockBefore utility
438+
/// function.
439+
BasicBlock *splitBasicBlockBefore(iterator I, const Twine &BBName = "");
440+
BasicBlock *splitBasicBlockBefore(Instruction *I, const Twine &BBName = "") {
441+
return splitBasicBlockBefore(I->getIterator(), BBName);
415442
}
416443

417444
/// Returns true if there are any uses of this basic block other than

llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,19 +244,33 @@ unsigned SplitAllCriticalEdges(Function &F,
244244
const CriticalEdgeSplittingOptions &Options =
245245
CriticalEdgeSplittingOptions());
246246

247-
/// Split the edge connecting specified block.
247+
/// Split the edge connecting the specified blocks, and return the newly created
248+
/// basic block between \p From and \p To.
248249
BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To,
249250
DominatorTree *DT = nullptr, LoopInfo *LI = nullptr,
250251
MemorySSAUpdater *MSSAU = nullptr);
251252

252-
/// Split the specified block at the specified instruction - everything before
253-
/// SplitPt stays in Old and everything starting with SplitPt moves to a new
254-
/// block. The two blocks are joined by an unconditional branch and the loop
255-
/// info is updated.
253+
/// Split the specified block at the specified instruction.
254+
///
255+
/// If \p Before is true, splitBlockBefore handles the block
256+
/// splitting. Otherwise, execution proceeds as described below.
257+
///
258+
/// Everything before \p SplitPt stays in \p Old and everything starting with \p
259+
/// SplitPt moves to a new block. The two blocks are joined by an unconditional
260+
/// branch. The new block with name \p BBName is returned.
256261
BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt,
257262
DominatorTree *DT = nullptr, LoopInfo *LI = nullptr,
258263
MemorySSAUpdater *MSSAU = nullptr,
259-
const Twine &BBName = "");
264+
const Twine &BBName = "", bool Before = false);
265+
266+
/// Split the specified block at the specified instruction \p SplitPt.
267+
/// All instructions before \p SplitPt are moved to a new block and all
268+
/// instructions after \p SplitPt stay in the old block. The new block and the
269+
/// old block are joined by inserting an unconditional branch to the end of the
270+
/// new block. The new block with name \p BBName is returned.
271+
BasicBlock *splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
272+
DominatorTree *DT, LoopInfo *LI,
273+
MemorySSAUpdater *MSSAU, const Twine &BBName = "");
260274

261275
/// This method introduces at least one new basic block into the function and
262276
/// moves some of the predecessors of BB to be predecessors of the new block.

llvm/lib/IR/BasicBlock.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,11 @@ bool BasicBlock::isLegalToHoistInto() const {
372372
return !Term->isExceptionalTerminator();
373373
}
374374

375-
BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) {
375+
BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName,
376+
bool Before) {
377+
if (Before)
378+
return splitBasicBlockBefore(I, BBName);
379+
376380
assert(getTerminator() && "Can't use splitBasicBlock on degenerate BB!");
377381
assert(I != InstList.end() &&
378382
"Trying to get me to create degenerate basic block!");
@@ -399,6 +403,40 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) {
399403
return New;
400404
}
401405

406+
BasicBlock *BasicBlock::splitBasicBlockBefore(iterator I, const Twine &BBName) {
407+
assert(getTerminator() &&
408+
"Can't use splitBasicBlockBefore on degenerate BB!");
409+
assert(I != InstList.end() &&
410+
"Trying to get me to create degenerate basic block!");
411+
412+
assert((!isa<PHINode>(*I) || getSinglePredecessor()) &&
413+
"cannot split on multi incoming phis");
414+
415+
BasicBlock *New = BasicBlock::Create(getContext(), BBName, getParent(), this);
416+
// Save DebugLoc of split point before invalidating iterator.
417+
DebugLoc Loc = I->getDebugLoc();
418+
// Move all of the specified instructions from the original basic block into
419+
// the new basic block.
420+
New->getInstList().splice(New->end(), this->getInstList(), begin(), I);
421+
422+
// Loop through all of the predecessors of the 'this' block (which will be the
423+
// predecessors of the New block), replace the specified successor 'this'
424+
// block to point at the New block and update any PHI nodes in 'this' block.
425+
// If there were PHI nodes in 'this' block, the PHI nodes are updated
426+
// to reflect that the incoming branches will be from the New block and not
427+
// from predecessors of the 'this' block.
428+
for (BasicBlock *Pred : predecessors(this)) {
429+
Instruction *TI = Pred->getTerminator();
430+
TI->replaceSuccessorWith(this, New);
431+
this->replacePhiUsesWith(Pred, New);
432+
}
433+
// Add a branch instruction from "New" to "this" Block.
434+
BranchInst *BI = BranchInst::Create(this, New);
435+
BI->setDebugLoc(Loc);
436+
437+
return New;
438+
}
439+
402440
void BasicBlock::replacePhiUsesWith(BasicBlock *Old, BasicBlock *New) {
403441
// N.B. This might not be a complete BasicBlock, so don't assume
404442
// that it ends with a non-phi instruction.

llvm/lib/Transforms/Utils/BasicBlockUtils.cpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, DominatorTree *DT,
510510
// block.
511511
assert(SP == BB && "CFG broken");
512512
SP = nullptr;
513-
return SplitBlock(Succ, &Succ->front(), DT, LI, MSSAU);
513+
return SplitBlock(Succ, &Succ->front(), DT, LI, MSSAU, "", /*Before=*/true);
514514
}
515515

516516
// Otherwise, if BB has a single successor, split it at the bottom of the
@@ -537,7 +537,10 @@ llvm::SplitAllCriticalEdges(Function &F,
537537

538538
BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
539539
DominatorTree *DT, LoopInfo *LI,
540-
MemorySSAUpdater *MSSAU, const Twine &BBName) {
540+
MemorySSAUpdater *MSSAU, const Twine &BBName,
541+
bool Before) {
542+
if (Before)
543+
return splitBlockBefore(Old, SplitPt, DT, LI, MSSAU, BBName);
541544
BasicBlock::iterator SplitIt = SplitPt->getIterator();
542545
while (isa<PHINode>(SplitIt) || SplitIt->isEHPad())
543546
++SplitIt;
@@ -569,6 +572,51 @@ BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
569572
return New;
570573
}
571574

575+
BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
576+
DominatorTree *DT, LoopInfo *LI,
577+
MemorySSAUpdater *MSSAU,
578+
const Twine &BBName) {
579+
580+
BasicBlock::iterator SplitIt = SplitPt->getIterator();
581+
while (isa<PHINode>(SplitIt) || SplitIt->isEHPad())
582+
++SplitIt;
583+
std::string Name = BBName.str();
584+
BasicBlock *New = Old->splitBasicBlock(
585+
SplitIt, Name.empty() ? Old->getName() + ".split" : Name,
586+
/* Before=*/true);
587+
588+
// The new block lives in whichever loop the old one did. This preserves
589+
// LCSSA as well, because we force the split point to be after any PHI nodes.
590+
if (LI)
591+
if (Loop *L = LI->getLoopFor(Old))
592+
L->addBasicBlockToLoop(New, *LI);
593+
594+
if (DT) {
595+
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
596+
SmallVector<DominatorTree::UpdateType, 8> DTUpdates;
597+
// New dominates Old. The predecessor nodes of the Old node dominate
598+
// New node.
599+
DTUpdates.push_back({DominatorTree::Insert, New, Old});
600+
for (BasicBlock *Pred : predecessors(New))
601+
if (DT->getNode(Pred)) {
602+
DTUpdates.push_back({DominatorTree::Insert, Pred, New});
603+
DTUpdates.push_back({DominatorTree::Delete, Pred, Old});
604+
}
605+
606+
DTU.applyUpdates(DTUpdates);
607+
DTU.flush();
608+
609+
// Move MemoryAccesses still tracked in Old, but part of New now.
610+
// Update accesses in successor blocks accordingly.
611+
if (MSSAU) {
612+
MSSAU->applyUpdates(DTUpdates, *DT);
613+
if (VerifyMemorySSA)
614+
MSSAU->getMemorySSA()->verifyMemorySSA();
615+
}
616+
}
617+
return New;
618+
}
619+
572620
/// Update DominatorTree, LoopInfo, and LCCSA analysis information.
573621
static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB,
574622
ArrayRef<BasicBlock *> Preds,

llvm/test/CodeGen/AMDGPU/call-constexpr.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ define amdgpu_kernel void @test_bitcast_use_workitem_id_x() #0 {
100100
; OPT-LABEL: @test_invoke(
101101
; OPT: %1 = bitcast float 2.000000e+00 to i32
102102
; OPT: %val = invoke i32 @ident_i32(i32 %1)
103-
; OPT-NEXT: to label %continue unwind label %broken
103+
; OPT-NEXT: to label %continue.split unwind label %broken
104104
; OPT-LABEL: continue.split:
105105
; OPT: bitcast i32 %val to float
106106
@_ZTIi = external global i8*

llvm/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
; CHECK: loop_begin.us1: ; preds = %loop_begin.backedge.us5, %.split.split.us
3737
; CHECK-NEXT: %var_val.us2 = load i32, i32* %var
3838
; CHECK-NEXT: switch i32 2, label %default.us-lcssa.us-lcssa.us [
39-
; CHECK-NEXT: i32 1, label %inc.us4
39+
; CHECK-NEXT: i32 1, label %inc.split.us
4040
; CHECK-NEXT: i32 2, label %dec.us3
4141
; CHECK-NEXT: ]
4242

@@ -50,15 +50,15 @@
5050
; CHECK: loop_begin: ; preds = %loop_begin.backedge, %.split.split
5151
; CHECK-NEXT: %var_val = load i32, i32* %var
5252
; CHECK-NEXT: switch i32 %c, label %default.us-lcssa.us-lcssa [
53-
; CHECK-NEXT: i32 1, label %inc
54-
; CHECK-NEXT: i32 2, label %dec
53+
; CHECK-NEXT: i32 1, label %inc.split
54+
; CHECK-NEXT: i32 2, label %dec.split
5555
; CHECK-NEXT: ]
5656

57-
; CHECK: inc: ; preds = %loop_begin
58-
; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa, label %inc.split
57+
; CHECK: inc.split: ; preds = %loop_begin
58+
; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa, label %inc
5959

60-
; CHECK: dec: ; preds = %loop_begin
61-
; CHECK-NEXT: br i1 true, label %us-unreachable6, label %dec.split
60+
; CHECK: dec.split: ; preds = %loop_begin
61+
; CHECK-NEXT: br i1 true, label %us-unreachable6, label %dec
6262

6363
define i32 @test(i32* %var) {
6464
%mem = alloca i32

0 commit comments

Comments
 (0)