[llvm] ab9f2be - Refactor some BasicBlockUtils functions (NFC)
Momchil Velikov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 19 10:21:20 PDT 2023
Author: Momchil Velikov
Date: 2023-07-19T18:18:22+01:00
New Revision: ab9f2bebd6d500537d85e828f6e44ee4740a99e1
URL: https://github.com/llvm/llvm-project/commit/ab9f2bebd6d500537d85e828f6e44ee4740a99e1
DIFF: https://github.com/llvm/llvm-project/commit/ab9f2bebd6d500537d85e828f6e44ee4740a99e1.diff
LOG: Refactor some BasicBlockUtils functions (NFC)
Add a more "flexible" `SplitBlockAndInsertIfThenElse` function
and re-implement some others on top of it.
Reviewed By: dmgreen
Differential Revision: https://reviews.llvm.org/D154052
Added:
Modified:
llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
index d65c2fe5fe6b38..84c1d80a676dd5 100644
--- a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -444,7 +444,44 @@ void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
Instruction **ThenTerm,
Instruction **ElseTerm,
MDNode *BranchWeights = nullptr,
- DomTreeUpdater *DTU = nullptr);
+ DomTreeUpdater *DTU = nullptr,
+ LoopInfo *LI = nullptr);
+
+/// Split the containing block at the specified instruction - everything before
+/// SplitBefore stays in the old basic block, and the rest of the instructions
+/// in the BB are moved to a new block. The two blocks are connected by a
+/// conditional branch (with value of Cmp being the condition).
+/// Before:
+/// Head
+/// SplitBefore
+/// Tail
+/// After:
+/// Head
+/// if (Cond)
+/// TrueBlock
+/// else
+//// FalseBlock
+/// SplitBefore
+/// Tail
+///
+/// If \p ThenBlock is null, the resulting CFG won't contain the TrueBlock. If
+/// \p ThenBlock is non-null and points to non-null BasicBlock pointer, that
+/// block will be inserted as the TrueBlock. Otherwise a new block will be
+/// created. Likewise for the \p ElseBlock parameter.
+/// If \p UnreachableThen or \p UnreachableElse is true, the corresponding newly
+/// created blocks will end with UnreachableInst, otherwise with branches to
+/// Tail. The function will not modify existing basic blocks passed to it. The
+/// caller must ensure that Tail is reachable from Head.
+/// Returns the newly created blocks in \p ThenBlock and \p ElseBlock.
+/// Updates DTU and LI if given.
+void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
+ BasicBlock **ThenBlock,
+ BasicBlock **ElseBlock,
+ bool UnreachableThen = false,
+ bool UnreachableElse = false,
+ MDNode *BranchWeights = nullptr,
+ DomTreeUpdater *DTU = nullptr,
+ LoopInfo *LI = nullptr);
/// Insert a for (int i = 0; i < End; i++) loop structure (with the exception
/// that \p End is assumed > 0, and thus not checked on entry) at \p
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 68ff16f70a5d59..a28b331ccdc7e9 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -1477,94 +1477,107 @@ Instruction *llvm::SplitBlockAndInsertIfThen(Value *Cond,
MDNode *BranchWeights,
DomTreeUpdater *DTU, LoopInfo *LI,
BasicBlock *ThenBlock) {
- SmallVector<DominatorTree::UpdateType, 8> Updates;
- BasicBlock *Head = SplitBefore->getParent();
- BasicBlock *Tail = Head->splitBasicBlock(SplitBefore->getIterator());
- if (DTU) {
- SmallPtrSet<BasicBlock *, 8> UniqueSuccessorsOfHead;
- Updates.push_back({DominatorTree::Insert, Head, Tail});
- Updates.reserve(Updates.size() + 2 * succ_size(Tail));
- for (BasicBlock *SuccessorOfHead : successors(Tail))
- if (UniqueSuccessorsOfHead.insert(SuccessorOfHead).second) {
- Updates.push_back({DominatorTree::Insert, Tail, SuccessorOfHead});
- Updates.push_back({DominatorTree::Delete, Head, SuccessorOfHead});
- }
- }
- Instruction *HeadOldTerm = Head->getTerminator();
- LLVMContext &C = Head->getContext();
- Instruction *CheckTerm;
- bool CreateThenBlock = (ThenBlock == nullptr);
- if (CreateThenBlock) {
- ThenBlock = BasicBlock::Create(C, "", Head->getParent(), Tail);
- if (Unreachable)
- CheckTerm = new UnreachableInst(C, ThenBlock);
- else {
- CheckTerm = BranchInst::Create(Tail, ThenBlock);
- if (DTU)
- Updates.push_back({DominatorTree::Insert, ThenBlock, Tail});
- }
- CheckTerm->setDebugLoc(SplitBefore->getDebugLoc());
- } else
- CheckTerm = ThenBlock->getTerminator();
- BranchInst *HeadNewTerm =
- BranchInst::Create(/*ifTrue*/ ThenBlock, /*ifFalse*/ Tail, Cond);
- if (DTU)
- Updates.push_back({DominatorTree::Insert, Head, ThenBlock});
- HeadNewTerm->setMetadata(LLVMContext::MD_prof, BranchWeights);
- ReplaceInstWithInst(HeadOldTerm, HeadNewTerm);
-
- if (DTU)
- DTU->applyUpdates(Updates);
-
- if (LI) {
- if (Loop *L = LI->getLoopFor(Head)) {
- // unreachable-terminated blocks cannot belong to any loop.
- if (!Unreachable)
- L->addBasicBlockToLoop(ThenBlock, *LI);
- L->addBasicBlockToLoop(Tail, *LI);
- }
- }
-
- return CheckTerm;
+ SplitBlockAndInsertIfThenElse(
+ Cond, SplitBefore, &ThenBlock, /* ElseBlock */ nullptr,
+ /* UnreachableThen */ Unreachable,
+ /* UnreachableElse */ false, BranchWeights, DTU, LI);
+ return ThenBlock->getTerminator();
}
void llvm::SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
Instruction **ThenTerm,
Instruction **ElseTerm,
MDNode *BranchWeights,
- DomTreeUpdater *DTU) {
- BasicBlock *Head = SplitBefore->getParent();
+ DomTreeUpdater *DTU, LoopInfo *LI) {
+ BasicBlock *ThenBlock = nullptr;
+ BasicBlock *ElseBlock = nullptr;
+ SplitBlockAndInsertIfThenElse(
+ Cond, SplitBefore, &ThenBlock, &ElseBlock, /* UnreachableThen */ false,
+ /* UnreachableElse */ false, BranchWeights, DTU, LI);
+
+ *ThenTerm = ThenBlock->getTerminator();
+ *ElseTerm = ElseBlock->getTerminator();
+}
+
+void llvm::SplitBlockAndInsertIfThenElse(
+ Value *Cond, Instruction *SplitBefore, BasicBlock **ThenBlock,
+ BasicBlock **ElseBlock, bool UnreachableThen, bool UnreachableElse,
+ MDNode *BranchWeights, DomTreeUpdater *DTU, LoopInfo *LI) {
+ assert((ThenBlock || ElseBlock) &&
+ "At least one branch block must be created");
+ assert((!UnreachableThen || !UnreachableElse) &&
+ "Split block tail must be reachable");
+ SmallVector<DominatorTree::UpdateType, 8> Updates;
SmallPtrSet<BasicBlock *, 8> UniqueOrigSuccessors;
- if (DTU)
+ BasicBlock *Head = SplitBefore->getParent();
+ if (DTU) {
UniqueOrigSuccessors.insert(succ_begin(Head), succ_end(Head));
+ Updates.reserve(4 + 2 * UniqueOrigSuccessors.size());
+ }
+ LLVMContext &C = Head->getContext();
BasicBlock *Tail = Head->splitBasicBlock(SplitBefore->getIterator());
+ BasicBlock *TrueBlock = Tail;
+ BasicBlock *FalseBlock = Tail;
+ bool ThenToTailEdge = false;
+ bool ElseToTailEdge = false;
+
+ // Encapsulate the logic around creation/insertion/etc of a new block.
+ auto handleBlock = [&](BasicBlock **PBB, bool Unreachable, BasicBlock *&BB,
+ bool &ToTailEdge) {
+ if (PBB == nullptr)
+ return; // Do not create/insert a block.
+
+ if (*PBB)
+ BB = *PBB; // Caller supplied block, use it.
+ else {
+ // Create a new block.
+ BB = BasicBlock::Create(C, "", Head->getParent(), Tail);
+ if (Unreachable)
+ (void)new UnreachableInst(C, BB);
+ else {
+ (void)BranchInst::Create(Tail, BB);
+ ToTailEdge = true;
+ }
+ BB->getTerminator()->setDebugLoc(SplitBefore->getDebugLoc());
+ // Pass the new block back to the caller.
+ *PBB = BB;
+ }
+ };
+
+ handleBlock(ThenBlock, UnreachableThen, TrueBlock, ThenToTailEdge);
+ handleBlock(ElseBlock, UnreachableElse, FalseBlock, ElseToTailEdge);
+
Instruction *HeadOldTerm = Head->getTerminator();
- LLVMContext &C = Head->getContext();
- BasicBlock *ThenBlock = BasicBlock::Create(C, "", Head->getParent(), Tail);
- BasicBlock *ElseBlock = BasicBlock::Create(C, "", Head->getParent(), Tail);
- *ThenTerm = BranchInst::Create(Tail, ThenBlock);
- (*ThenTerm)->setDebugLoc(SplitBefore->getDebugLoc());
- *ElseTerm = BranchInst::Create(Tail, ElseBlock);
- (*ElseTerm)->setDebugLoc(SplitBefore->getDebugLoc());
BranchInst *HeadNewTerm =
- BranchInst::Create(/*ifTrue*/ThenBlock, /*ifFalse*/ElseBlock, Cond);
+ BranchInst::Create(/*ifTrue*/ TrueBlock, /*ifFalse*/ FalseBlock, Cond);
HeadNewTerm->setMetadata(LLVMContext::MD_prof, BranchWeights);
ReplaceInstWithInst(HeadOldTerm, HeadNewTerm);
+
if (DTU) {
- SmallVector<DominatorTree::UpdateType, 8> Updates;
- Updates.reserve(4 + 2 * UniqueOrigSuccessors.size());
- for (BasicBlock *Succ : successors(Head)) {
- Updates.push_back({DominatorTree::Insert, Head, Succ});
- Updates.push_back({DominatorTree::Insert, Succ, Tail});
- }
+ Updates.emplace_back(DominatorTree::Insert, Head, TrueBlock);
+ Updates.emplace_back(DominatorTree::Insert, Head, FalseBlock);
+ if (ThenToTailEdge)
+ Updates.emplace_back(DominatorTree::Insert, TrueBlock, Tail);
+ if (ElseToTailEdge)
+ Updates.emplace_back(DominatorTree::Insert, FalseBlock, Tail);
for (BasicBlock *UniqueOrigSuccessor : UniqueOrigSuccessors)
- Updates.push_back({DominatorTree::Insert, Tail, UniqueOrigSuccessor});
+ Updates.emplace_back(DominatorTree::Insert, Tail, UniqueOrigSuccessor);
for (BasicBlock *UniqueOrigSuccessor : UniqueOrigSuccessors)
- Updates.push_back({DominatorTree::Delete, Head, UniqueOrigSuccessor});
+ Updates.emplace_back(DominatorTree::Delete, Head, UniqueOrigSuccessor);
DTU->applyUpdates(Updates);
}
+
+ if (LI) {
+ if (Loop *L = LI->getLoopFor(Head); L) {
+ if (ThenToTailEdge)
+ L->addBasicBlockToLoop(TrueBlock, *LI);
+ if (ElseToTailEdge)
+ L->addBasicBlockToLoop(FalseBlock, *LI);
+ L->addBasicBlockToLoop(Tail, *LI);
+ }
+ }
}
std::pair<Instruction*, Value*>
More information about the llvm-commits
mailing list