diff options
author | Momchil Velikov <momchil.velikov@arm.com> | 2023-07-19 17:27:56 +0100 |
---|---|---|
committer | Momchil Velikov <momchil.velikov@arm.com> | 2023-07-19 18:18:22 +0100 |
commit | ab9f2bebd6d500537d85e828f6e44ee4740a99e1 (patch) | |
tree | 4ece5cc15c13fdcf01e10924a8b25d274173fe38 /llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | |
parent | 8acdcf4016876d122733991561be706b64026e73 (diff) | |
download | llvm-ab9f2bebd6d500537d85e828f6e44ee4740a99e1.zip llvm-ab9f2bebd6d500537d85e828f6e44ee4740a99e1.tar.gz llvm-ab9f2bebd6d500537d85e828f6e44ee4740a99e1.tar.bz2 |
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
Diffstat (limited to 'llvm/lib/Transforms/Utils/BasicBlockUtils.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 149 |
1 files changed, 81 insertions, 68 deletions
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index 68ff16f..a28b331 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*> |