diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/ADCE.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/GVN.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/JumpThreading.cpp | 78 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 64 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 173 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopRotationUtils.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUtils.cpp | 6 |
10 files changed, 200 insertions, 168 deletions
diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp index ce09a477b5f..1cda09a5781 100644 --- a/llvm/lib/Transforms/Scalar/ADCE.cpp +++ b/llvm/lib/Transforms/Scalar/ADCE.cpp @@ -30,9 +30,10 @@ #include "llvm/IR/CFG.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" -#include "llvm/IR/IRBuilder.h" #include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" @@ -614,8 +615,8 @@ void AggressiveDeadCodeElimination::updateDeadRegions() { } } - DT.applyUpdates(DeletedEdges); - PDT.applyUpdates(DeletedEdges); + DomTreeUpdater(DT, PDT, DomTreeUpdater::UpdateStrategy::Eager) + .applyUpdates(DeletedEdges); NumBranchesRemoved += 1; } diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 2f2d7f620a2..99402985f28 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -19,7 +19,6 @@ #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LazyValueInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" @@ -28,6 +27,7 @@ #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstrTypes.h" @@ -44,6 +44,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/Local.h" #include <cassert> #include <utility> @@ -308,6 +309,7 @@ static bool processCmp(CmpInst *C, LazyValueInfo *LVI) { /// a case fires on every incoming edge then the entire switch can be removed /// and replaced with a branch to the case destination. static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI, DominatorTree *DT) { + DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Lazy); Value *Cond = SI->getCondition(); BasicBlock *BB = SI->getParent(); @@ -372,7 +374,7 @@ static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI, DominatorTree *DT) ++NumDeadCases; Changed = true; if (--SuccessorsCount[Succ] == 0) - DT->deleteEdge(BB, Succ); + DTU.deleteEdge(BB, Succ); continue; } if (State == LazyValueInfo::True) { @@ -389,15 +391,11 @@ static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI, DominatorTree *DT) ++CI; } - if (Changed) { + if (Changed) // If the switch has been simplified to the point where it can be replaced // by a branch then do so now. - DeferredDominance DDT(*DT); ConstantFoldTerminator(BB, /*DeleteDeadConditions = */ false, - /*TLI = */ nullptr, &DDT); - DDT.flush(); - } - + /*TLI = */ nullptr, &DTU); return Changed; } diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 1e0a22cb14b..00336bb5742 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -38,7 +38,6 @@ #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/PHITransAddr.h" #include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Attributes.h" @@ -48,6 +47,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" @@ -71,6 +71,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/VNCoercion.h" #include <algorithm> @@ -2028,12 +2029,13 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT, bool Changed = false; bool ShouldContinue = true; + DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); // Merge unconditional branches, allowing PRE to catch more // optimization opportunities. for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ) { BasicBlock *BB = &*FI++; - bool removedBlock = MergeBlockIntoPredecessor(BB, DT, LI, MD); + bool removedBlock = MergeBlockIntoPredecessor(BB, &DTU, LI, MD); if (removedBlock) ++NumGVNBlocks; diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 1d66472f93c..7b738fd5086 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -30,7 +30,6 @@ #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" @@ -38,6 +37,7 @@ #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" @@ -65,6 +65,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include <algorithm> @@ -285,7 +286,7 @@ bool JumpThreading::runOnFunction(Function &F) { auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); auto LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI(); auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); - DeferredDominance DDT(*DT); + DomTreeUpdater DTU(*DT, DomTreeUpdater::UpdateStrategy::Lazy); std::unique_ptr<BlockFrequencyInfo> BFI; std::unique_ptr<BranchProbabilityInfo> BPI; bool HasProfileData = F.hasProfileData(); @@ -295,7 +296,7 @@ bool JumpThreading::runOnFunction(Function &F) { BFI.reset(new BlockFrequencyInfo(F, *BPI, LI)); } - bool Changed = Impl.runImpl(F, TLI, LVI, AA, &DDT, HasProfileData, + bool Changed = Impl.runImpl(F, TLI, LVI, AA, &DTU, HasProfileData, std::move(BFI), std::move(BPI)); if (PrintLVIAfterJumpThreading) { dbgs() << "LVI for function '" << F.getName() << "':\n"; @@ -312,7 +313,7 @@ PreservedAnalyses JumpThreadingPass::run(Function &F, auto &DT = AM.getResult<DominatorTreeAnalysis>(F); auto &LVI = AM.getResult<LazyValueAnalysis>(F); auto &AA = AM.getResult<AAManager>(F); - DeferredDominance DDT(DT); + DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy); std::unique_ptr<BlockFrequencyInfo> BFI; std::unique_ptr<BranchProbabilityInfo> BPI; @@ -322,7 +323,7 @@ PreservedAnalyses JumpThreadingPass::run(Function &F, BFI.reset(new BlockFrequencyInfo(F, *BPI, LI)); } - bool Changed = runImpl(F, &TLI, &LVI, &AA, &DDT, HasProfileData, + bool Changed = runImpl(F, &TLI, &LVI, &AA, &DTU, HasProfileData, std::move(BFI), std::move(BPI)); if (!Changed) @@ -336,14 +337,14 @@ PreservedAnalyses JumpThreadingPass::run(Function &F, bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo *LVI_, AliasAnalysis *AA_, - DeferredDominance *DDT_, bool HasProfileData_, + DomTreeUpdater *DTU_, bool HasProfileData_, std::unique_ptr<BlockFrequencyInfo> BFI_, std::unique_ptr<BranchProbabilityInfo> BPI_) { LLVM_DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n"); TLI = TLI_; LVI = LVI_; AA = AA_; - DDT = DDT_; + DTU = DTU_; BFI.reset(); BPI.reset(); // When profile data is available, we need to update edge weights after @@ -360,7 +361,9 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, // JumpThreading must not processes blocks unreachable from entry. It's a // waste of compute time and can potentially lead to hangs. SmallPtrSet<BasicBlock *, 16> Unreachable; - DominatorTree &DT = DDT->flush(); + assert(DTU && "DTU isn't passed into JumpThreading before using it."); + assert(DTU->hasDomTree() && "JumpThreading relies on DomTree to proceed."); + DominatorTree &DT = DTU->getDomTree(); for (auto &BB : F) if (!DT.isReachableFromEntry(&BB)) Unreachable.insert(&BB); @@ -379,7 +382,7 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, // Stop processing BB if it's the entry or is now deleted. The following // routines attempt to eliminate BB and locating a suitable replacement // for the entry is non-trivial. - if (&BB == &F.getEntryBlock() || DDT->pendingDeletedBB(&BB)) + if (&BB == &F.getEntryBlock() || DTU->isBBPendingDeletion(&BB)) continue; if (pred_empty(&BB)) { @@ -390,7 +393,7 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, << '\n'); LoopHeaders.erase(&BB); LVI->eraseBlock(&BB); - DeleteDeadBlock(&BB, DDT); + DeleteDeadBlock(&BB, DTU); Changed = true; continue; } @@ -404,9 +407,9 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, // Don't alter Loop headers and latches to ensure another pass can // detect and transform nested loops later. !LoopHeaders.count(&BB) && !LoopHeaders.count(BI->getSuccessor(0)) && - TryToSimplifyUncondBranchFromEmptyBlock(&BB, DDT)) { - // BB is valid for cleanup here because we passed in DDT. F remains - // BB's parent until a DDT->flush() event. + TryToSimplifyUncondBranchFromEmptyBlock(&BB, DTU)) { + // BB is valid for cleanup here because we passed in DTU. F remains + // BB's parent until a DTU->getDomTree() event. LVI->eraseBlock(&BB); Changed = true; } @@ -415,7 +418,8 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, } while (Changed); LoopHeaders.clear(); - DDT->flush(); + // Flush only the Dominator Tree. + DTU->getDomTree(); LVI->enableDT(); return EverChanged; } @@ -609,7 +613,7 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors( // "X < 4" and "X < 3" is known true but "X < 4" itself is not available. // Perhaps getConstantOnEdge should be smart enough to do this? - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -626,7 +630,7 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors( /// If I is a PHI node, then we know the incoming values for any constants. if (PHINode *PN = dyn_cast<PHINode>(I)) { - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -759,7 +763,7 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors( const DataLayout &DL = PN->getModule()->getDataLayout(); // We can do this simplification if any comparisons fold to true or false. // See if any do. - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -806,7 +810,7 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors( if (!isa<Instruction>(CmpLHS) || cast<Instruction>(CmpLHS)->getParent() != BB) { - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -838,7 +842,7 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors( match(CmpLHS, m_Add(m_Value(AddLHS), m_ConstantInt(AddConst)))) { if (!isa<Instruction>(AddLHS) || cast<Instruction>(AddLHS)->getParent() != BB) { - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -923,7 +927,7 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors( } // If all else fails, see if LVI can figure out a constant value for us. - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -974,7 +978,7 @@ static bool hasAddressTakenAndUsed(BasicBlock *BB) { bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { // If the block is trivially dead, just return and let the caller nuke it. // This simplifies other transformations. - if (DDT->pendingDeletedBB(BB) || + if (DTU->isBBPendingDeletion(BB) || (pred_empty(BB) && BB != &BB->getParent()->getEntryBlock())) return false; @@ -991,7 +995,7 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { LoopHeaders.insert(BB); LVI->eraseBlock(SinglePred); - MergeBasicBlockIntoOnlyPred(BB, nullptr, DDT); + MergeBasicBlockIntoOnlyPred(BB, DTU); // Now that BB is merged into SinglePred (i.e. SinglePred Code followed by // BB code within one basic block `BB`), we need to invalidate the LVI @@ -1088,7 +1092,7 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { << "' folding undef terminator: " << *BBTerm << '\n'); BranchInst::Create(BBTerm->getSuccessor(BestSucc), BBTerm); BBTerm->eraseFromParent(); - DDT->applyUpdates(Updates); + DTU->applyUpdates(Updates); return true; } @@ -1100,7 +1104,7 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { << "' folding terminator: " << *BB->getTerminator() << '\n'); ++NumFolds; - ConstantFoldTerminator(BB, true, nullptr, DDT); + ConstantFoldTerminator(BB, true, nullptr, DTU); return true; } @@ -1127,7 +1131,7 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { // threading is concerned. assert(CondBr->isConditional() && "Threading on unconditional terminator"); - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -1156,7 +1160,7 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { ConstantInt::getFalse(CondCmp->getType()); ReplaceFoldableUses(CondCmp, CI); } - DDT->deleteEdge(BB, ToRemoveSucc); + DTU->deleteEdgeRelaxed(BB, ToRemoveSucc); return true; } @@ -1240,7 +1244,7 @@ bool JumpThreadingPass::ProcessImpliedCondition(BasicBlock *BB) { RemoveSucc->removePredecessor(BB); BranchInst::Create(KeepSucc, BI); BI->eraseFromParent(); - DDT->deleteEdge(BB, RemoveSucc); + DTU->deleteEdgeRelaxed(BB, RemoveSucc); return true; } CurrentBB = CurrentPred; @@ -1667,7 +1671,7 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB, TerminatorInst *Term = BB->getTerminator(); BranchInst::Create(OnlyDest, Term); Term->eraseFromParent(); - DDT->applyUpdates(Updates); + DTU->applyUpdates(Updates); // If the condition is now dead due to the removal of the old terminator, // erase it. @@ -1945,7 +1949,7 @@ bool JumpThreadingPass::ThreadEdge(BasicBlock *BB, << "' with cost: " << JumpThreadCost << ", across block:\n " << *BB << "\n"); - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -2009,7 +2013,7 @@ bool JumpThreadingPass::ThreadEdge(BasicBlock *BB, } // Enqueue required DT updates. - DDT->applyUpdates({{DominatorTree::Insert, NewBB, SuccBB}, + DTU->applyUpdates({{DominatorTree::Insert, NewBB, SuccBB}, {DominatorTree::Insert, PredBB, NewBB}, {DominatorTree::Delete, PredBB, BB}}); @@ -2105,7 +2109,7 @@ BasicBlock *JumpThreadingPass::SplitBlockPreds(BasicBlock *BB, BFI->setBlockFreq(NewBB, NewBBFreq.getFrequency()); } - DDT->applyUpdates(Updates); + DTU->applyUpdates(Updates); return NewBBs[0]; } @@ -2378,7 +2382,7 @@ bool JumpThreadingPass::DuplicateCondBranchOnPHIIntoPred( // Remove the unconditional branch at the end of the PredBB block. OldPredBranch->eraseFromParent(); - DDT->applyUpdates(Updates); + DTU->applyUpdates(Updates); ++NumDupes; return true; @@ -2421,7 +2425,7 @@ bool JumpThreadingPass::TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) { // Now check if one of the select values would allow us to constant fold the // terminator in BB. We don't do the transform if both sides fold, those // cases will be threaded in any case. - if (DDT->pending()) + if (DTU->hasPendingDomTreeUpdates()) LVI->disableDT(); else LVI->enableDT(); @@ -2455,7 +2459,7 @@ bool JumpThreadingPass::TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) { // The select is now dead. SI->eraseFromParent(); - DDT->applyUpdates({{DominatorTree::Insert, NewBB, BB}, + DTU->applyUpdates({{DominatorTree::Insert, NewBB, BB}, {DominatorTree::Insert, Pred, NewBB}}); // Update any other PHI nodes in BB. for (BasicBlock::iterator BI = BB->begin(); @@ -2548,12 +2552,12 @@ bool JumpThreadingPass::TryToUnfoldSelectInCurrBB(BasicBlock *BB) { Updates.push_back({DominatorTree::Insert, BB, SplitBB}); Updates.push_back({DominatorTree::Insert, BB, NewBB}); Updates.push_back({DominatorTree::Insert, NewBB, SplitBB}); - // BB's successors were moved to SplitBB, update DDT accordingly. + // BB's successors were moved to SplitBB, update DTU accordingly. for (auto *Succ : successors(SplitBB)) { Updates.push_back({DominatorTree::Delete, BB, Succ}); Updates.push_back({DominatorTree::Insert, SplitBB, Succ}); } - DDT->applyUpdates(Updates); + DTU->applyUpdates(Updates); return true; } return false; @@ -2664,7 +2668,7 @@ bool JumpThreadingPass::ThreadGuard(BasicBlock *BB, IntrinsicInst *Guard, // DuplicateInstructionsInSplitBetween inserts a new block "BB.split" between // PredBB and BB. We need to perform two inserts and one delete for each of // the above calls to update Dominators. - DDT->applyUpdates( + DTU->applyUpdates( {// Guarded block split. {DominatorTree::Delete, PredGuardedBlock, BB}, {DominatorTree::Insert, PredGuardedBlock, GuardedBlock}, diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp index 2b83d3dc5f1..3f31d8efeb4 100644 --- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp +++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp @@ -27,6 +27,7 @@ #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" @@ -41,6 +42,7 @@ using namespace llvm; static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE) { bool Changed = false; + DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); // Copy blocks into a temporary array to avoid iterator invalidation issues // as we remove them. SmallVector<WeakTrackingVH, 16> Blocks(L.blocks()); @@ -57,7 +59,7 @@ static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI, continue; // Merge Succ into Pred and delete it. - MergeBlockIntoPredecessor(Succ, &DT, &LI); + MergeBlockIntoPredecessor(Succ, &DTU, &LI); SE.forgetLoop(&L); Changed = true; diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index 0de2bc72b52..5d3e928d509 100644 --- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -28,7 +28,6 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" @@ -38,6 +37,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -65,6 +65,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" #include <algorithm> #include <cassert> @@ -2534,9 +2535,10 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT, // Delete any unreachable statepoints so that we don't have unrewritten // statepoints surviving this pass. This makes testing easier and the // resulting IR less confusing to human readers. - DeferredDominance DD(DT); - bool MadeChange = removeUnreachableBlocks(F, nullptr, &DD); - DD.flush(); + DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy); + bool MadeChange = removeUnreachableBlocks(F, nullptr, &DTU); + // Flush the Dominator Tree. + DTU.getDomTree(); // Gather all the statepoints which need rewritten. Be careful to only // consider those in reachable code since we need to ask dominance queries diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index 516a785dce1..7f61477d961 100644 --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -20,11 +20,12 @@ #include "llvm/Analysis/CFG.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" -#include "llvm/Transforms/Utils/Local.h" +#include "llvm/Analysis/PostDominators.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" @@ -37,6 +38,7 @@ #include "llvm/IR/Value.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/Casting.h" +#include "llvm/Transforms/Utils/Local.h" #include <cassert> #include <cstdint> #include <string> @@ -45,7 +47,7 @@ using namespace llvm; -void llvm::DeleteDeadBlock(BasicBlock *BB, DeferredDominance *DDT) { +void llvm::DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU) { assert((pred_begin(BB) == pred_end(BB) || // Can delete self loop. BB->getSinglePredecessor() == BB) && "Block is not dead!"); @@ -54,11 +56,11 @@ void llvm::DeleteDeadBlock(BasicBlock *BB, DeferredDominance *DDT) { // Loop through all of our successors and make sure they know that one // of their predecessors is going away. - if (DDT) + if (DTU) Updates.reserve(BBTerm->getNumSuccessors()); for (BasicBlock *Succ : BBTerm->successors()) { Succ->removePredecessor(BB); - if (DDT) + if (DTU) Updates.push_back({DominatorTree::Delete, BB, Succ}); } @@ -74,10 +76,15 @@ void llvm::DeleteDeadBlock(BasicBlock *BB, DeferredDominance *DDT) { I.replaceAllUsesWith(UndefValue::get(I.getType())); BB->getInstList().pop_back(); } - - if (DDT) { - DDT->applyUpdates(Updates); - DDT->deleteBB(BB); // Deferred deletion of BB. + new UnreachableInst(BB->getContext(), BB); + assert(BB->getInstList().size() == 1 && + isa<UnreachableInst>(BB->getTerminator()) && + "The successor list of BB isn't empty before " + "applying corresponding DTU updates."); + + if (DTU) { + DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); + DTU->deleteBB(BB); } else { BB->eraseFromParent(); // Zap the block! } @@ -115,11 +122,9 @@ bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI) { return Changed; } -bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT, +bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU, LoopInfo *LI, - MemoryDependenceResults *MemDep, - DeferredDominance *DDT) { - assert(!(DT && DDT) && "Cannot call with both DT and DDT."); + MemoryDependenceResults *MemDep) { if (BB->hasAddressTaken()) return false; @@ -154,10 +159,10 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT, FoldSingleEntryPHINodes(BB, MemDep); } - // Deferred DT update: Collect all the edges that exit BB. These - // dominator edges will be redirected from Pred. + // DTU update: Collect all the edges that exit BB. + // These dominator edges will be redirected from Pred. std::vector<DominatorTree::UpdateType> Updates; - if (DDT) { + if (DTU) { Updates.reserve(1 + (2 * succ_size(BB))); Updates.push_back({DominatorTree::Delete, PredBB, BB}); for (auto I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { @@ -175,6 +180,7 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT, // Move all definitions in the successor to the predecessor... PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); + new UnreachableInst(BB->getContext(), BB); // Eliminate duplicate dbg.values describing the entry PHI node post-splice. for (auto Incoming : IncomingValues) { @@ -195,28 +201,24 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT, if (!PredBB->hasName()) PredBB->takeName(BB); - // Finally, erase the old block and update dominator info. - if (DT) - if (DomTreeNode *DTN = DT->getNode(BB)) { - DomTreeNode *PredDTN = DT->getNode(PredBB); - SmallVector<DomTreeNode *, 8> Children(DTN->begin(), DTN->end()); - for (DomTreeNode *DI : Children) - DT->changeImmediateDominator(DI, PredDTN); - - DT->eraseNode(BB); - } - if (LI) LI->removeBlock(BB); if (MemDep) MemDep->invalidateCachedPredecessors(); - if (DDT) { - DDT->deleteBB(BB); // Deferred deletion of BB. - DDT->applyUpdates(Updates); - } else { - BB->eraseFromParent(); // Nuke BB. + // Finally, erase the old block and update dominator info. + if (DTU) { + assert(BB->getInstList().size() == 1 && + isa<UnreachableInst>(BB->getTerminator()) && + "The successor list of BB isn't empty before " + "applying corresponding DTU updates."); + DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); + DTU->deleteBB(BB); + } + + else { + BB->eraseFromParent(); // Nuke BB if DTU is nullptr. } return true; } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index ae3cb077a3a..0c3afc4e403 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -47,6 +47,7 @@ #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/GetElementPtrTypeIterator.h" @@ -102,7 +103,7 @@ STATISTIC(NumRemoved, "Number of unreachable basic blocks removed"); /// DeleteDeadConditions is true. bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, const TargetLibraryInfo *TLI, - DeferredDominance *DDT) { + DomTreeUpdater *DTU) { TerminatorInst *T = BB->getTerminator(); IRBuilder<> Builder(T); @@ -125,8 +126,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, // Replace the conditional branch with an unconditional one. Builder.CreateBr(Destination); BI->eraseFromParent(); - if (DDT) - DDT->deleteEdge(BB, OldDest); + if (DTU) + DTU->deleteEdgeRelaxed(BB, OldDest); return true; } @@ -201,8 +202,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, DefaultDest->removePredecessor(ParentBB); i = SI->removeCase(i); e = SI->case_end(); - if (DDT) - DDT->deleteEdge(ParentBB, DefaultDest); + if (DTU) + DTU->deleteEdgeRelaxed(ParentBB, DefaultDest); continue; } @@ -229,7 +230,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, Builder.CreateBr(TheOnlyDest); BasicBlock *BB = SI->getParent(); std::vector <DominatorTree::UpdateType> Updates; - if (DDT) + if (DTU) Updates.reserve(SI->getNumSuccessors() - 1); // Remove entries from PHI nodes which we no longer branch to... @@ -239,7 +240,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, TheOnlyDest = nullptr; // Don't modify the first branch to TheOnlyDest } else { Succ->removePredecessor(BB); - if (DDT) + if (DTU) Updates.push_back({DominatorTree::Delete, BB, Succ}); } } @@ -249,8 +250,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, SI->eraseFromParent(); if (DeleteDeadConditions) RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI); - if (DDT) - DDT->applyUpdates(Updates); + if (DTU) + DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); return true; } @@ -297,7 +298,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, dyn_cast<BlockAddress>(IBI->getAddress()->stripPointerCasts())) { BasicBlock *TheOnlyDest = BA->getBasicBlock(); std::vector <DominatorTree::UpdateType> Updates; - if (DDT) + if (DTU) Updates.reserve(IBI->getNumDestinations() - 1); // Insert the new branch. @@ -310,7 +311,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, BasicBlock *ParentBB = IBI->getParent(); BasicBlock *DestBB = IBI->getDestination(i); DestBB->removePredecessor(ParentBB); - if (DDT) + if (DTU) Updates.push_back({DominatorTree::Delete, ParentBB, DestBB}); } } @@ -327,8 +328,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, new UnreachableInst(BB->getContext(), BB); } - if (DDT) - DDT->applyUpdates(Updates); + if (DTU) + DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); return true; } } @@ -626,7 +627,7 @@ bool llvm::SimplifyInstructionsInBlock(BasicBlock *BB, /// .. and delete the predecessor corresponding to the '1', this will attempt to /// recursively fold the and to 0. void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, - DeferredDominance *DDT) { + DomTreeUpdater *DTU) { // This only adjusts blocks with PHI nodes. if (!isa<PHINode>(BB->begin())) return; @@ -649,17 +650,16 @@ void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, // of the block. if (PhiIt != OldPhiIt) PhiIt = &BB->front(); } - if (DDT) - DDT->deleteEdge(Pred, BB); + if (DTU) + DTU->deleteEdgeRelaxed(Pred, BB); } /// MergeBasicBlockIntoOnlyPred - DestBB is a block with one predecessor and its /// predecessor is known to have one successor (DestBB!). Eliminate the edge /// between them, moving the instructions in the predecessor into DestBB and /// deleting the predecessor block. -void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, DominatorTree *DT, - DeferredDominance *DDT) { - assert(!(DT && DDT) && "Cannot call with both DT and DDT."); +void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, + DomTreeUpdater *DTU) { // If BB has single-entry PHI nodes, fold them. while (PHINode *PN = dyn_cast<PHINode>(DestBB->begin())) { @@ -677,10 +677,11 @@ void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, DominatorTree *DT, if (PredBB == &DestBB->getParent()->getEntryBlock()) ReplaceEntryBB = true; - // Deferred DT update: Collect all the edges that enter PredBB. These - // dominator edges will be redirected to DestBB. + // DTU updates: Collect all the edges that enter + // PredBB. These dominator edges will be redirected to DestBB. std::vector <DominatorTree::UpdateType> Updates; - if (DDT && !ReplaceEntryBB) { + + if (DTU) { Updates.reserve(1 + (2 * pred_size(PredBB))); Updates.push_back({DominatorTree::Delete, PredBB, DestBB}); for (auto I = pred_begin(PredBB), E = pred_end(PredBB); I != E; ++I) { @@ -708,33 +709,32 @@ void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, DominatorTree *DT, // Splice all the instructions from PredBB to DestBB. PredBB->getTerminator()->eraseFromParent(); DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); + new UnreachableInst(PredBB->getContext(), PredBB); // If the PredBB is the entry block of the function, move DestBB up to // become the entry block after we erase PredBB. if (ReplaceEntryBB) DestBB->moveAfter(PredBB); - if (DT) { - // For some irreducible CFG we end up having forward-unreachable blocks - // so check if getNode returns a valid node before updating the domtree. - if (DomTreeNode *DTN = DT->getNode(PredBB)) { - BasicBlock *PredBBIDom = DTN->getIDom()->getBlock(); - DT->changeImmediateDominator(DestBB, PredBBIDom); - DT->eraseNode(PredBB); + if (DTU) { + assert(PredBB->getInstList().size() == 1 && + isa<UnreachableInst>(PredBB->getTerminator()) && + "The successor list of PredBB isn't empty before " + "applying corresponding DTU updates."); + DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); + DTU->deleteBB(PredBB); + // Recalculation of DomTree is needed when updating a forward DomTree and + // the Entry BB is replaced. + if (ReplaceEntryBB && DTU->hasDomTree()) { + // The entry block was removed and there is no external interface for + // the dominator tree to be notified of this change. In this corner-case + // we recalculate the entire tree. + DTU->recalculate(*(DestBB->getParent())); } } - if (DDT) { - DDT->deleteBB(PredBB); // Deferred deletion of BB. - if (ReplaceEntryBB) - // The entry block was removed and there is no external interface for the - // dominator tree to be notified of this change. In this corner-case we - // recalculate the entire tree. - DDT->recalculate(*(DestBB->getParent())); - else - DDT->applyUpdates(Updates); - } else { - PredBB->eraseFromParent(); // Nuke BB. + else { + PredBB->eraseFromParent(); // Nuke BB if DTU is nullptr. } } @@ -945,7 +945,7 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB, /// eliminate BB by rewriting all the predecessors to branch to the successor /// block and return true. If we can't transform, return false. bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB, - DeferredDominance *DDT) { + DomTreeUpdater *DTU) { assert(BB != &BB->getParent()->getEntryBlock() && "TryToSimplifyUncondBranchFromEmptyBlock called on entry block!"); @@ -987,7 +987,7 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB, LLVM_DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB); std::vector<DominatorTree::UpdateType> Updates; - if (DDT) { + if (DTU) { Updates.reserve(1 + (2 * pred_size(BB))); Updates.push_back({DominatorTree::Delete, BB, Succ}); // All predecessors of BB will be moved to Succ. @@ -1044,9 +1044,16 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB, BB->replaceAllUsesWith(Succ); if (!Succ->hasName()) Succ->takeName(BB); - if (DDT) { - DDT->deleteBB(BB); // Deferred deletion of the old basic block. - DDT->applyUpdates(Updates); + // Clear the successor list of BB to match updates applying to DTU later. + if (BB->getTerminator()) + BB->getInstList().pop_back(); + new UnreachableInst(BB->getContext(), BB); + assert(succ_empty(BB) && "The successor list of BB isn't empty before " + "applying corresponding DTU updates."); + + if (DTU) { + DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); + DTU->deleteBB(BB); } else { BB->eraseFromParent(); // Delete the old basic block. } @@ -1902,17 +1909,17 @@ unsigned llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) { } unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap, - bool PreserveLCSSA, DeferredDominance *DDT) { + bool PreserveLCSSA, DomTreeUpdater *DTU) { BasicBlock *BB = I->getParent(); std::vector <DominatorTree::UpdateType> Updates; // Loop over all of the successors, removing BB's entry from any PHI // nodes. - if (DDT) + if (DTU) Updates.reserve(BB->getTerminator()->getNumSuccessors()); for (BasicBlock *Successor : successors(BB)) { Successor->removePredecessor(BB, PreserveLCSSA); - if (DDT) + if (DTU) Updates.push_back({DominatorTree::Delete, BB, Successor}); } // Insert a call to llvm.trap right before this. This turns the undefined @@ -1934,13 +1941,13 @@ unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap, BB->getInstList().erase(BBI++); ++NumInstrsRemoved; } - if (DDT) - DDT->applyUpdates(Updates); + if (DTU) + DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); return NumInstrsRemoved; } /// changeToCall - Convert the specified invoke into a normal call. -static void changeToCall(InvokeInst *II, DeferredDominance *DDT = nullptr) { +static void changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr) { SmallVector<Value*, 8> Args(II->arg_begin(), II->arg_end()); SmallVector<OperandBundleDef, 1> OpBundles; II->getOperandBundlesAsDefs(OpBundles); @@ -1961,8 +1968,8 @@ static void changeToCall(InvokeInst *II, DeferredDominance *DDT = nullptr) { BasicBlock *UnwindDestBB = II->getUnwindDest(); UnwindDestBB->removePredecessor(BB); II->eraseFromParent(); - if (DDT) - DDT->deleteEdge(BB, UnwindDestBB); + if (DTU) + DTU->deleteEdgeRelaxed(BB, UnwindDestBB); } BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI, @@ -2003,8 +2010,8 @@ BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI, } static bool markAliveBlocks(Function &F, - SmallPtrSetImpl<BasicBlock*> &Reachable, - DeferredDominance *DDT = nullptr) { + SmallPtrSetImpl<BasicBlock *> &Reachable, + DomTreeUpdater *DTU = nullptr) { SmallVector<BasicBlock*, 128> Worklist; BasicBlock *BB = &F.front(); Worklist.push_back(BB); @@ -2029,7 +2036,7 @@ static bool markAliveBlocks(Function &F, if (IntrinsicID == Intrinsic::assume) { if (match(CI->getArgOperand(0), m_CombineOr(m_Zero(), m_Undef()))) { // Don't insert a call to llvm.trap right before the unreachable. - changeToUnreachable(CI, false, false, DDT); + changeToUnreachable(CI, false, false, DTU); Changed = true; break; } @@ -2046,7 +2053,7 @@ static bool markAliveBlocks(Function &F, if (match(CI->getArgOperand(0), m_Zero())) if (!isa<UnreachableInst>(CI->getNextNode())) { changeToUnreachable(CI->getNextNode(), /*UseLLVMTrap=*/false, - false, DDT); + false, DTU); Changed = true; break; } @@ -2054,7 +2061,7 @@ static bool markAliveBlocks(Function &F, } else if ((isa<ConstantPointerNull>(Callee) && !NullPointerIsDefined(CI->getFunction())) || isa<UndefValue>(Callee)) { - changeToUnreachable(CI, /*UseLLVMTrap=*/false, false, DDT); + changeToUnreachable(CI, /*UseLLVMTrap=*/false, false, DTU); Changed = true; break; } @@ -2064,7 +2071,7 @@ static bool markAliveBlocks(Function &F, // though. if (!isa<UnreachableInst>(CI->getNextNode())) { // Don't insert a call to llvm.trap right before the unreachable. - changeToUnreachable(CI->getNextNode(), false, false, DDT); + changeToUnreachable(CI->getNextNode(), false, false, DTU); Changed = true; } break; @@ -2083,7 +2090,7 @@ static bool markAliveBlocks(Function &F, (isa<ConstantPointerNull>(Ptr) && !NullPointerIsDefined(SI->getFunction(), SI->getPointerAddressSpace()))) { - changeToUnreachable(SI, true, false, DDT); + changeToUnreachable(SI, true, false, DTU); Changed = true; break; } @@ -2097,7 +2104,7 @@ static bool markAliveBlocks(Function &F, if ((isa<ConstantPointerNull>(Callee) && !NullPointerIsDefined(BB->getParent())) || isa<UndefValue>(Callee)) { - changeToUnreachable(II, true, false, DDT); + changeToUnreachable(II, true, false, DTU); Changed = true; } else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(&F)) { if (II->use_empty() && II->onlyReadsMemory()) { @@ -2107,10 +2114,10 @@ static bool markAliveBlocks(Function &F, BranchInst::Create(NormalDestBB, II); UnwindDestBB->removePredecessor(II->getParent()); II->eraseFromParent(); - if (DDT) - DDT->deleteEdge(BB, UnwindDestBB); + if (DTU) + DTU->deleteEdgeRelaxed(BB, UnwindDestBB); } else - changeToCall(II, DDT); + changeToCall(II, DTU); Changed = true; } } else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Terminator)) { @@ -2156,7 +2163,7 @@ static bool markAliveBlocks(Function &F, } } - Changed |= ConstantFoldTerminator(BB, true, nullptr, DDT); + Changed |= ConstantFoldTerminator(BB, true, nullptr, DTU); for (BasicBlock *Successor : successors(BB)) if (Reachable.insert(Successor).second) Worklist.push_back(Successor); @@ -2164,11 +2171,11 @@ static bool markAliveBlocks(Function &F, return Changed; } -void llvm::removeUnwindEdge(BasicBlock *BB, DeferredDominance *DDT) { +void llvm::removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU) { TerminatorInst *TI = BB->getTerminator(); if (auto *II = dyn_cast<InvokeInst>(TI)) { - changeToCall(II, DDT); + changeToCall(II, DTU); return; } @@ -2196,8 +2203,8 @@ void llvm::removeUnwindEdge(BasicBlock *BB, DeferredDominance *DDT) { UnwindDest->removePredecessor(BB); TI->replaceAllUsesWith(NewTI); TI->eraseFromParent(); - if (DDT) - DDT->deleteEdge(BB, UnwindDest); + if (DTU) + DTU->deleteEdgeRelaxed(BB, UnwindDest); } /// removeUnreachableBlocks - Remove blocks that are not reachable, even @@ -2205,9 +2212,9 @@ void llvm::removeUnwindEdge(BasicBlock *BB, DeferredDominance *DDT) { /// otherwise. If `LVI` is passed, this function preserves LazyValueInfo /// after modifying the CFG. bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI, - DeferredDominance *DDT) { + DomTreeUpdater *DTU) { SmallPtrSet<BasicBlock*, 16> Reachable; - bool Changed = markAliveBlocks(F, Reachable, DDT); + bool Changed = markAliveBlocks(F, Reachable, DTU); // If there are unreachable blocks in the CFG... if (Reachable.size() == F.size()) @@ -2217,7 +2224,7 @@ bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI, NumRemoved += F.size()-Reachable.size(); // Loop over all of the basic blocks that are not reachable, dropping all of - // their internal references. Update DDT and LVI if available. + // their internal references. Update DTU and LVI if available. std::vector <DominatorTree::UpdateType> Updates; for (Function::iterator I = ++F.begin(), E = F.end(); I != E; ++I) { auto *BB = &*I; @@ -2226,30 +2233,40 @@ bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI, for (BasicBlock *Successor : successors(BB)) { if (Reachable.count(Successor)) Successor->removePredecessor(BB); - if (DDT) + if (DTU) Updates.push_back({DominatorTree::Delete, BB, Successor}); } if (LVI) LVI->eraseBlock(BB); BB->dropAllReferences(); } - + SmallVector<BasicBlock *, 8> ToDeleteBBs; for (Function::iterator I = ++F.begin(); I != F.end();) { auto *BB = &*I; if (Reachable.count(BB)) { ++I; continue; } - if (DDT) { - DDT->deleteBB(BB); // deferred deletion of BB. + if (DTU) { + ToDeleteBBs.push_back(BB); + + // Remove the TerminatorInst of BB to clear the successor list of BB. + if (BB->getTerminator()) + BB->getInstList().pop_back(); + new UnreachableInst(BB->getContext(), BB); + assert(succ_empty(BB) && "The successor list of BB isn't empty before " + "applying corresponding DTU updates."); ++I; } else { I = F.getBasicBlockList().erase(I); } } - if (DDT) - DDT->applyUpdates(Updates); + if (DTU) { + DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); + for (auto *BB : ToDeleteBBs) + DTU->deleteBB(BB); + } return true; } diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index 6e92e679f99..0f58f18bc87 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -23,10 +23,10 @@ #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/CFG.h" #include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/IntrinsicInst.h" @@ -35,6 +35,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -476,7 +477,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { // the OrigHeader block into OrigLatch. This will succeed if they are // connected by an unconditional branch. This is just a cleanup so the // emitted code isn't too gross in this common case. - MergeBlockIntoPredecessor(OrigHeader, DT, LI); + DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); + MergeBlockIntoPredecessor(OrigHeader, &DTU, LI); LLVM_DEBUG(dbgs() << "LoopRotation: into "; L->dump()); diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 46af120a428..8e9235b6261 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -26,6 +26,7 @@ #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" @@ -1425,12 +1426,13 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr, // Remove the old branch. Preheader->getTerminator()->eraseFromParent(); + DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); if (DT) { // Update the dominator tree by informing it about the new edge from the // preheader to the exit. - DT->insertEdge(Preheader, ExitBlock); + DTU.insertEdge(Preheader, ExitBlock); // Inform the dominator tree about the removed edge. - DT->deleteEdge(Preheader, L->getHeader()); + DTU.deleteEdge(Preheader, L->getHeader()); } // Given LCSSA form is satisfied, we should not have users of instructions |