[llvm] [CodeGenPrepare][NFC] Reland: Update the dominator tree instead of rebuilding it (PR #179040)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 1 03:23:04 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Mingjie Xu (Enna1)
<details>
<summary>Changes</summary>
The original differential revision is https://reviews.llvm.org/D153638
Reverted in https://github.com/llvm/llvm-project/commit/f5b5a30858f32e237636acd296b6d0f87c1dfe97 because of causing a clang crash.
This patch relands it with the crash fixed. In the `while (MadeChange)`
loop, `optimizeBlock()` and `eliminateFallThrough()` can delete blocks,
we need to flush awaiting deletion in each iteration.
Depends on https://github.com/llvm/llvm-project/pull/178895
---
Patch is 28.85 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/179040.diff
3 Files Affected:
- (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+106-78)
- (modified) llvm/lib/Transforms/Utils/BasicBlockUtils.cpp (+20-45)
- (modified) llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp (+25)
``````````diff
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index b9cf73a48ee22..9a6051aee0f8a 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -24,6 +24,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/FloatingPointPredicateUtils.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -253,6 +254,15 @@ static cl::opt<bool> EnableICMP_EQToICMP_ST(
"cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false),
cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
+#ifdef EXPENSIVE_CHECKS
+static bool VerifyDT = true;
+#else
+static bool VerifyDT = false;
+#endif
+static cl::opt<bool, true> VerifyDTUpdates(
+ "cgp-verify-dt-updates", cl::location(VerifyDT), cl::Hidden,
+ cl::desc("Verify dominator tree updates in CodeGenPrepare"));
+
static cl::opt<bool>
VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false),
cl::desc("Enable BFI update verification for "
@@ -312,6 +322,8 @@ class CodeGenPrepare {
const TargetTransformInfo *TTI = nullptr;
const BasicBlockSectionsProfileReader *BBSectionsProfileReader = nullptr;
const TargetLibraryInfo *TLInfo = nullptr;
+ DominatorTree *DT = nullptr;
+ DomTreeUpdater *DTU = nullptr;
LoopInfo *LI = nullptr;
std::unique_ptr<BlockFrequencyInfo> BFI;
std::unique_ptr<BranchProbabilityInfo> BPI;
@@ -363,10 +375,6 @@ class CodeGenPrepare {
/// DataLayout for the Function being processed.
const DataLayout *DL = nullptr;
- /// Building the dominator tree can be expensive, so we only build it
- /// lazily and update it when required.
- std::unique_ptr<DominatorTree> DT;
-
public:
CodeGenPrepare() = default;
CodeGenPrepare(const TargetMachine *TM) : TM(TM){};
@@ -409,16 +417,12 @@ class CodeGenPrepare {
}
}
- // Get the DominatorTree, building if necessary.
- DominatorTree &getDT(Function &F) {
- if (!DT)
- DT = std::make_unique<DominatorTree>(F);
- return *DT;
- }
+ // Get the DominatorTree, updating it if necessary.
+ DominatorTree &getDT() { return DTU->getDomTree(); }
void removeAllAssertingVHReferences(Value *V);
bool eliminateAssumptions(Function &F);
- bool eliminateFallThrough(Function &F, DominatorTree *DT = nullptr);
+ bool eliminateFallThrough(Function &F);
bool eliminateMostlyEmptyBlocks(Function &F);
BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
bool canMergeBlocks(const BasicBlock *BB, const BasicBlock *DestBB) const;
@@ -466,7 +470,7 @@ class CodeGenPrepare {
Instruction *&Inst, bool AllowPromotionWithoutCommonHeader,
bool HasPromoted, TypePromotionTransaction &TPT,
SmallVectorImpl<Instruction *> &SpeculativelyMovedExts);
- bool splitBranchCondition(Function &F, ModifyDT &ModifiedDT);
+ bool splitBranchCondition(Function &F);
bool simplifyOffsetableRelocate(GCStatepointInst &I);
bool tryToSinkFreeOperands(Instruction *I);
@@ -497,6 +501,7 @@ class CodeGenPrepareLegacyPass : public FunctionPass {
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<TargetPassConfig>();
AU.addRequired<TargetTransformInfoWrapperPass>();
+ AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<LoopInfoWrapperPass>();
AU.addUsedIfAvailable<BasicBlockSectionsProfileReaderWrapperPass>();
}
@@ -517,6 +522,7 @@ bool CodeGenPrepareLegacyPass::runOnFunction(Function &F) {
CGP.TRI = CGP.SubtargetInfo->getRegisterInfo();
CGP.TLInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
CGP.TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ CGP.DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
CGP.LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
CGP.BPI.reset(new BranchProbabilityInfo(F, *CGP.LI));
CGP.BFI.reset(new BlockFrequencyInfo(F, *CGP.BPI, *CGP.LI));
@@ -531,6 +537,7 @@ bool CodeGenPrepareLegacyPass::runOnFunction(Function &F) {
INITIALIZE_PASS_BEGIN(CodeGenPrepareLegacyPass, DEBUG_TYPE,
"Optimize for code generation", false, false)
INITIALIZE_PASS_DEPENDENCY(BasicBlockSectionsProfileReaderWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
@@ -564,6 +571,7 @@ bool CodeGenPrepare::run(Function &F, FunctionAnalysisManager &AM) {
TRI = SubtargetInfo->getRegisterInfo();
TLInfo = &AM.getResult<TargetLibraryAnalysis>(F);
TTI = &AM.getResult<TargetIRAnalysis>(F);
+ DT = &AM.getResult<DominatorTreeAnalysis>(F);
LI = &AM.getResult<LoopAnalysis>(F);
BPI.reset(new BranchProbabilityInfo(F, *LI));
BFI.reset(new BlockFrequencyInfo(F, *BPI, *LI));
@@ -601,6 +609,9 @@ bool CodeGenPrepare::_run(Function &F) {
(void)F.setSectionPrefix("unknown");
}
+ DomTreeUpdater DTUpdater(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+ DTU = &DTUpdater;
+
/// This optimization identifies DIV instructions that can be
/// profitably bypassed and carried out with a shorter, faster divide.
if (!OptSize && !PSI->hasHugeWorkingSetSize() && TLI->isSlowDivBypassed()) {
@@ -626,29 +637,34 @@ bool CodeGenPrepare::_run(Function &F) {
// unconditional branch.
EverMadeChange |= eliminateMostlyEmptyBlocks(F);
- ModifyDT ModifiedDT = ModifyDT::NotModifyDT;
if (!DisableBranchOpts)
- EverMadeChange |= splitBranchCondition(F, ModifiedDT);
+ EverMadeChange |= splitBranchCondition(F);
// Split some critical edges where one of the sources is an indirect branch,
// to help generate sane code for PHIs involving such edges.
EverMadeChange |=
SplitIndirectBrCriticalEdges(F, /*IgnoreBlocksWithoutPHI=*/true);
+ // Transformations above may invalidate dominator tree and/or loop info.
+ if (EverMadeChange) {
+ DTU->recalculate(F);
+ LI->releaseMemory();
+ LI->analyze(DTU->getDomTree());
+ }
+
// If we are optimzing huge function, we need to consider the build time.
// Because the basic algorithm's complex is near O(N!).
IsHugeFunc = F.size() > HugeFuncThresholdInCGPP;
- // Transformations above may invalidate dominator tree and/or loop info.
- DT.reset();
- LI->releaseMemory();
- LI->analyze(getDT(F));
-
bool MadeChange = true;
bool FuncIterated = false;
while (MadeChange) {
MadeChange = false;
+ // Flush pending updates as we may delete BasicBlocks in previous iteration
+ // of the current loop.
+ DTU->flush();
+
for (BasicBlock &BB : llvm::make_early_inc_range(F)) {
if (FuncIterated && !FreshBBs.contains(&BB))
continue;
@@ -656,9 +672,6 @@ bool CodeGenPrepare::_run(Function &F) {
ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT;
bool Changed = optimizeBlock(BB, ModifiedDTOnIteration);
- if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT)
- DT.reset();
-
MadeChange |= Changed;
if (IsHugeFunc) {
// If the BB is updated, it may still has chance to be optimized.
@@ -691,11 +704,15 @@ bool CodeGenPrepare::_run(Function &F) {
MadeChange |= optimizePhiTypes(F);
if (MadeChange)
- eliminateFallThrough(F, DT.get());
+ eliminateFallThrough(F);
#ifndef NDEBUG
- if (MadeChange && VerifyLoopInfo)
- LI->verify(getDT(F));
+ if (VerifyDT)
+ assert(getDT().verify(DominatorTree::VerificationLevel::Fast) &&
+ "Incorrect DominatorTree updates in CGP");
+
+ if (VerifyLoopInfo)
+ LI->verify(getDT());
#endif
// Really free removed instructions during promotion.
@@ -713,6 +730,9 @@ bool CodeGenPrepare::_run(Function &F) {
NewGEPBases.clear();
SunkAddrs.clear();
+ // LoopInfo is not needed anymore and ConstantFoldTerminator can break it.
+ LI = nullptr;
+
if (!DisableBranchOpts) {
MadeChange = false;
// Use a set vector to get deterministic iteration order. The order the
@@ -721,7 +741,7 @@ bool CodeGenPrepare::_run(Function &F) {
SmallSetVector<BasicBlock *, 8> WorkList;
for (BasicBlock &BB : F) {
SmallVector<BasicBlock *, 2> Successors(successors(&BB));
- MadeChange |= ConstantFoldTerminator(&BB, true);
+ MadeChange |= ConstantFoldTerminator(&BB, true, nullptr, DTU);
if (!MadeChange)
continue;
@@ -736,13 +756,16 @@ bool CodeGenPrepare::_run(Function &F) {
BasicBlock *BB = WorkList.pop_back_val();
SmallVector<BasicBlock *, 2> Successors(successors(BB));
- DeleteDeadBlock(BB);
+ DeleteDeadBlock(BB, DTU);
for (BasicBlock *Succ : Successors)
if (pred_empty(Succ))
WorkList.insert(Succ);
}
+ // Flush pending DT updates in order to finalise deletion of dead blocks.
+ DTU->flush();
+
// Merge pairs of basic blocks with unconditional branches, connected by
// a single edge.
if (EverMadeChange || MadeChange)
@@ -829,7 +852,7 @@ void CodeGenPrepare::removeAllAssertingVHReferences(Value *V) {
/// Merge basic blocks which are connected by a single edge, where one of the
/// basic blocks has a single successor pointing to the other basic block,
/// which has a single predecessor.
-bool CodeGenPrepare::eliminateFallThrough(Function &F, DominatorTree *DT) {
+bool CodeGenPrepare::eliminateFallThrough(Function &F) {
bool Changed = false;
// Scan all of the blocks in the function, except for the entry block.
// Use a temporary array to avoid iterator being invalidated when
@@ -850,19 +873,13 @@ bool CodeGenPrepare::eliminateFallThrough(Function &F, DominatorTree *DT) {
if (!SinglePred || SinglePred == BB || BB->hasAddressTaken())
continue;
- // Make an effort to skip unreachable blocks.
- if (DT && !DT->isReachableFromEntry(BB))
- continue;
-
BranchInst *Term = dyn_cast<BranchInst>(SinglePred->getTerminator());
if (Term && !Term->isConditional()) {
Changed = true;
LLVM_DEBUG(dbgs() << "To merge:\n" << *BB << "\n\n\n");
// Merge BB into SinglePred and delete it.
- MergeBlockIntoPredecessor(BB, /* DTU */ nullptr, LI, /* MSSAU */ nullptr,
- /* MemDep */ nullptr,
- /* PredecessorWithTwoSuccessors */ false, DT);
+ MergeBlockIntoPredecessor(BB, DTU, LI);
Preds.insert(SinglePred);
if (IsHugeFunc) {
@@ -1120,6 +1137,7 @@ static void replaceAllUsesWith(Value *Old, Value *New,
/// Eliminate a basic block that has only phi's and an unconditional branch in
/// it.
+/// Indicate that the DT was modified only if the DT wasn't updated.
void CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
BranchInst *BI = cast<BranchInst>(BB->getTerminator());
BasicBlock *DestBB = BI->getSuccessor(0);
@@ -1563,7 +1581,7 @@ bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
// Finally, we need to ensure that the insert point will dominate all
// existing uses of the increment.
- auto &DT = getDT(*BO->getParent()->getParent());
+ auto &DT = getDT();
if (DT.dominates(Cmp->getParent(), BO->getParent()))
// If we're moving up the dom tree, all uses are trivially dominated.
// (This is the common case for code produced by LSR.)
@@ -2552,7 +2570,8 @@ static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI,
/// %ctz = phi i64 [ 64, %entry ], [ %z, %cond.false ]
///
/// If the transform is performed, return true and set ModifiedDT to true.
-static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI,
+static bool despeculateCountZeros(IntrinsicInst *CountZeros,
+ DomTreeUpdater &DTU, LoopInfo &LI,
const TargetLowering *TLI,
const DataLayout *DL, ModifyDT &ModifiedDT,
SmallPtrSet<BasicBlock *, 32> &FreshBBs,
@@ -2580,7 +2599,8 @@ static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI,
// The intrinsic will be sunk behind a compare against zero and branch.
BasicBlock *StartBlock = CountZeros->getParent();
- BasicBlock *CallBlock = StartBlock->splitBasicBlock(CountZeros, "cond.false");
+ BasicBlock *CallBlock = SplitBlock(StartBlock, CountZeros, &DTU, &LI,
+ /* MSSAU */ nullptr, "cond.false");
if (IsHugeFunc)
FreshBBs.insert(CallBlock);
@@ -2590,17 +2610,11 @@ static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI,
BasicBlock::iterator SplitPt = std::next(BasicBlock::iterator(CountZeros));
// Any debug-info after CountZeros should not be included.
SplitPt.setHeadBit(true);
- BasicBlock *EndBlock = CallBlock->splitBasicBlock(SplitPt, "cond.end");
+ BasicBlock *EndBlock = SplitBlock(CallBlock, &*SplitPt, &DTU, &LI,
+ /* MSSAU */ nullptr, "cond.end");
if (IsHugeFunc)
FreshBBs.insert(EndBlock);
- // Update the LoopInfo. The new blocks are in the same loop as the start
- // block.
- if (Loop *L = LI.getLoopFor(StartBlock)) {
- L->addBasicBlockToLoop(CallBlock, LI);
- L->addBasicBlockToLoop(EndBlock, LI);
- }
-
// Set up a builder to create a compare, conditional branch, and PHI.
IRBuilder<> Builder(CountZeros->getContext());
Builder.SetInsertPoint(StartBlock->getTerminator());
@@ -2615,6 +2629,7 @@ static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI,
Value *Cmp = Builder.CreateICmpEQ(Op, Zero, "cmpz");
Builder.CreateCondBr(Cmp, EndBlock, CallBlock);
StartBlock->getTerminator()->eraseFromParent();
+ DTU.applyUpdates({{DominatorTree::Insert, StartBlock, EndBlock}});
// Create a PHI in the end block to select either the output of the intrinsic
// or the bit width of the operand.
@@ -2766,7 +2781,7 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
case Intrinsic::cttz:
case Intrinsic::ctlz:
// If counting zeros is expensive, try to avoid it.
- return despeculateCountZeros(II, *LI, TLI, DL, ModifiedDT, FreshBBs,
+ return despeculateCountZeros(II, *DTU, *LI, TLI, DL, ModifiedDT, FreshBBs,
IsHugeFunc);
case Intrinsic::fshl:
case Intrinsic::fshr:
@@ -3092,7 +3107,7 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
continue;
// Duplicate the return into TailCallBB.
- (void)FoldReturnIntoUncondBranch(RetI, BB, TailCallBB);
+ (void)FoldReturnIntoUncondBranch(RetI, BB, TailCallBB, DTU);
assert(!VerifyBFIUpdates ||
BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
BFI->setBlockFreq(BB,
@@ -3112,7 +3127,7 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
ClonedInst->insertBefore(CI->getIterator());
}
}
- BB->eraseFromParent();
+ DTU->deleteBB(BB);
}
return Changed;
@@ -5888,10 +5903,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
// Defer the query (and possible computation of) the dom tree to point of
// actual use. It's expected that most address matches don't actually need
// the domtree.
- auto getDTFn = [MemoryInst, this]() -> const DominatorTree & {
- Function *F = MemoryInst->getParent()->getParent();
- return this->getDT(*F);
- };
+ auto getDTFn = [this]() -> const DominatorTree & { return getDT(); };
ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
*TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
@@ -5953,7 +5965,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
// TODO: Adjust insert point considering (Base|Scaled)Reg if possible.
if (!SunkAddr) {
- auto &DT = getDT(*MemoryInst->getFunction());
+ auto &DT = getDT();
if ((AddrMode.BaseReg && !DT.dominates(AddrMode.BaseReg, &*InsertPos)) ||
(AddrMode.ScaledReg && !DT.dominates(AddrMode.ScaledReg, &*InsertPos)))
return Modified;
@@ -6463,9 +6475,11 @@ bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *I, bool IsSigned,
unsigned VTHalfBitWidth = Ty->getScalarSizeInBits() / 2;
Type *LegalTy = Ty->getWithNewBitWidth(VTHalfBitWidth);
+ SmallVector<DominatorTree::UpdateType, 8> DTUpdates;
+
// New BBs:
BasicBlock *OverflowEntryBB =
- I->getParent()->splitBasicBlock(I, "", /*Before*/ true);
+ SplitBlock(I->getParent(), I, DTU, LI, nullptr, "", /*Before*/ true);
OverflowEntryBB->takeName(I->getParent());
// Keep the 'br' instruction that is generated as a result of the split to be
// erased/replaced later.
@@ -6508,6 +6522,8 @@ bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *I, bool IsSigned,
IsAnyBitTrue = Builder.CreateOr(CmpLHS, CmpRHS, "or.lhs.rhs");
}
Builder.CreateCondBr(IsAnyBitTrue, OverflowBB, NoOverflowBB);
+ DTUpdates.push_back({DominatorTree::Insert, OverflowEntryBB, OverflowBB});
+ DTUpdates.push_back({DominatorTree::Insert, OverflowEntryBB, NoOverflowBB});
// BB overflow.no:
Builder.SetInsertPoint(NoOverflowBB);
@@ -6532,6 +6548,9 @@ bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *I, bool IsSigned,
// No we don't need the old terminator in overflow.entry BB, erase it:
OldTerminator->eraseFromParent();
+ DTUpdates.push_back({DominatorTree::Insert, NoOverflowBB, OverflowResBB});
+ DTUpdates.push_back({DominatorTree::Delete, OverflowEntryBB, OverflowResBB});
+
// BB overflow.res:
Builder.SetInsertPoint(OverflowResBB, OverflowResBB->getFirstInsertionPt());
// Create PHI nodes to merge results from no.overflow BB and overflow BB to
@@ -6564,11 +6583,14 @@ bool CodeGenPrepare::optimizeMulWithOverflow(Instruction *I, bool IsSigned,
Value *MulOverflow = Builder.CreateExtractValue(I, {0}, "mul.overflow");
Value *OverflowFlag = Builder.CreateExtractValue(I, {1}, "overflow.flag");
Builder.CreateBr(OverflowResBB);
+ DTUpdates.push_back({DominatorTree::Insert, OverflowBB, OverflowResBB});
// Add The Extracted values to the PHINodes in the overflow.res BB.
OverflowResPHI->addIncoming(MulOverflow, OverflowBB);
OverflowFlagPHI->addIncoming(OverflowFlag, OverflowBB);
+ DTU->applyUpdates(DTUpdates);
+
ModifiedDT = ModifyDT::ModifyBBDT;
return true;
}
@@ -6764,7 +6786,7 @@ bool CodeGenPrepare::mergeSExts(Function &F) {
continue;
bool inserted = false;
for (auto &Pt : CurPts) {
- if (getDT(F).dominates(Inst, Pt)) {
+ if (getDT().dominates(Inst, Pt)) {
replaceAllUsesWith(Pt, Inst, FreshBBs, IsHugeFunc);
RemovedInsts.insert(Pt);
Pt->removeFromParent();
@@ -6773,7 +6795,7 @@ bool CodeGenPrepare::mergeSExts(Function &F) {
Changed = true;
break;
}
- if (!getDT(F).dominates(Pt, Inst))
+ if (!getDT().dominates(Pt, Inst))
// Give up if we need to merge in a common dominator as the
// experiments show it is not profitable.
continue;
@@ -6869,7 +6891,7 @@ 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(), LI);
NewBaseInsertPt = NewBaseInsertBB->getFirstInsertionPt();
} else
NewBaseInsertPt = std::next(BaseI->getIterator());
@@ -7739,12 +7761,6 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
llvm::shouldOptimizeForSize(SI->getParent(), PSI, BFI.get())))
return false;
- // The DominatorTree needs to be rebuilt by any consumers after this
- // transformation. We simply reset here rather than setting the ModifiedDT
- // flag to avoid restarting the function walk in runOnFunction for each
- // select optimized.
- DT.reset();
-
// Transform a sequence like this:
// start:
// %cmp = cmp uge i32 %a, %...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/179040
More information about the llvm-commits
mailing list