diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 207 |
1 files changed, 171 insertions, 36 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 21412dc..8b580f5 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -68,7 +68,8 @@ STATISTIC(NumRemoved, "Number of unreachable basic blocks removed"); /// conditions and indirectbr addresses this might make dead if /// DeleteDeadConditions is true. bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, + DominatorTree *DT) { TerminatorInst *T = BB->getTerminator(); IRBuilder<> Builder(T); @@ -95,6 +96,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, // Replace the conditional branch with an unconditional one. Builder.CreateBr(Destination); BI->eraseFromParent(); + if (DT && OldDest != Destination && OldDest != BB) + DT->deleteEdge(BB, OldDest); return true; } @@ -165,9 +168,17 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, createBranchWeights(Weights)); } // Remove this entry. - DefaultDest->removePredecessor(SI->getParent()); + BasicBlock *ParentBB = SI->getParent(); + DefaultDest->removePredecessor(ParentBB); i = SI->removeCase(i); e = SI->case_end(); + if (DT && DefaultDest != ParentBB) { + // DefaultDest may still be a successor of a non-default case. + if (none_of(successors(ParentBB), [DefaultDest](BasicBlock *S) { + return S == DefaultDest; + })) + DT->deleteEdge(ParentBB, DefaultDest); + } continue; } @@ -193,19 +204,29 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, // Insert the new branch. Builder.CreateBr(TheOnlyDest); BasicBlock *BB = SI->getParent(); + BasicBlock *TheOnlyDestCheck = TheOnlyDest; + std::vector<DominatorTree::UpdateType> Updates; // Remove entries from PHI nodes which we no longer branch to... for (BasicBlock *Succ : SI->successors()) { // Found case matching a constant operand? - if (Succ == TheOnlyDest) + if (Succ == TheOnlyDest) { TheOnlyDest = nullptr; // Don't modify the first branch to TheOnlyDest - else + } else { Succ->removePredecessor(BB); + if (DT && Succ != TheOnlyDestCheck && Succ != BB) { + DominatorTree::UpdateType UT = {DominatorTree::Delete, BB, Succ}; + if (std::find(Updates.begin(), Updates.end(), UT) == Updates.end()) + Updates.push_back(UT); + } + } } // Delete the old switch. Value *Cond = SI->getCondition(); SI->eraseFromParent(); + if (DT && !Updates.empty()) + DT->applyUpdates(Updates); if (DeleteDeadConditions) RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI); return true; @@ -253,17 +274,30 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, if (BlockAddress *BA = dyn_cast<BlockAddress>(IBI->getAddress()->stripPointerCasts())) { BasicBlock *TheOnlyDest = BA->getBasicBlock(); + BasicBlock *TheOnlyDestCheck = TheOnlyDest; + std::vector<DominatorTree::UpdateType> Updates; // Insert the new branch. Builder.CreateBr(TheOnlyDest); for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) { - if (IBI->getDestination(i) == TheOnlyDest) + if (IBI->getDestination(i) == TheOnlyDest) { TheOnlyDest = nullptr; - else - IBI->getDestination(i)->removePredecessor(IBI->getParent()); + } else { + BasicBlock *ParentBB = IBI->getParent(); + BasicBlock *DestBB = IBI->getDestination(i); + DestBB->removePredecessor(ParentBB); + if (DT && DestBB != TheOnlyDestCheck && DestBB != ParentBB) { + DominatorTree::UpdateType UT = {DominatorTree::Delete, ParentBB, + DestBB}; + if (std::find(Updates.begin(), Updates.end(), UT) == Updates.end()) + Updates.push_back(UT); + } + } } Value *Address = IBI->getAddress(); IBI->eraseFromParent(); + if (DT && !Updates.empty()) + DT->applyUpdates(Updates); if (DeleteDeadConditions) RecursivelyDeleteTriviallyDeadInstructions(Address, TLI); @@ -553,7 +587,8 @@ 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) { +void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, + DominatorTree *DT) { // This only adjusts blocks with PHI nodes. if (!isa<PHINode>(BB->begin())) return; @@ -576,6 +611,8 @@ void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred) { // of the block. if (PhiIt != OldPhiIt) PhiIt = &BB->front(); } + if (DT && BB != Pred) + DT->deleteEdge(Pred, BB); } @@ -597,6 +634,23 @@ void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, DominatorTree *DT) { BasicBlock *PredBB = DestBB->getSinglePredecessor(); assert(PredBB && "Block doesn't have a single predecessor!"); + // Collect all the edges that enter PredBB, discarding edges to itself and + // duplicates. These dominator edges will be redirected to DestBB. + std::vector<DominatorTree::UpdateType> Updates; + if (DT) + for (pred_iterator PI = pred_begin(PredBB), E = pred_end(PredBB); PI != E; + ++PI) { + if (*PI == PredBB) + continue; + DominatorTree::UpdateType UT = {DominatorTree::Delete, *PI, PredBB}; + if (std::find(Updates.begin(), Updates.end(), UT) == Updates.end()) { + Updates.push_back(UT); + // DestBB cannot dominate itself. + if (*PI != DestBB) + Updates.push_back({DominatorTree::Insert, *PI, DestBB}); + } + } + // Zap anything that took the address of DestBB. Not doing this will give the // address an invalid value. if (DestBB->hasAddressTaken()) { @@ -617,16 +671,25 @@ void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, DominatorTree *DT) { // If the PredBB is the entry block of the function, move DestBB up to // become the entry block after we erase PredBB. - if (PredBB == &DestBB->getParent()->getEntryBlock()) + bool ReplacedEntryBB = false; + if (PredBB == &DestBB->getParent()->getEntryBlock()) { DestBB->moveAfter(PredBB); + ReplacedEntryBB = true; + } - if (DT) { - BasicBlock *PredBBIDom = DT->getNode(PredBB)->getIDom()->getBlock(); - DT->changeImmediateDominator(DestBB, PredBBIDom); - DT->eraseNode(PredBB); + if (DT && !ReplacedEntryBB) { + Updates.push_back({DominatorTree::Delete, PredBB, DestBB}); + DT->applyUpdates(Updates); } + // Nuke BB. PredBB->eraseFromParent(); + + // 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. + if (DT && ReplacedEntryBB) + DT->recalculate(*(DestBB->getParent())); } /// CanMergeValues - Return true if we can choose one of these values to use @@ -834,7 +897,8 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB, /// potential side-effect free intrinsics and the branch. If possible, /// 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) { +bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB, + DominatorTree *DT) { assert(BB != &BB->getParent()->getEntryBlock() && "TryToSimplifyUncondBranchFromEmptyBlock called on entry block!"); @@ -875,6 +939,20 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) { DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB); + // Collect all the edges that enter BB, discarding edges to itself and + // duplicates. These dominator edges will be redirected to Succ. + std::vector<DominatorTree::UpdateType> Updates; + if (DT) + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + if (*PI == BB) + continue; + DominatorTree::UpdateType UT = {DominatorTree::Delete, *PI, BB}; + if (std::find(Updates.begin(), Updates.end(), UT) == Updates.end()) { + Updates.push_back(UT); + Updates.push_back({DominatorTree::Insert, *PI, Succ}); + } + } + if (isa<PHINode>(Succ->begin())) { // If there is more than one pred of succ, and there are PHI nodes in // the successor, then we need to add incoming edges for the PHI nodes @@ -909,16 +987,27 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) { // add the metadata to the branch instructions in the predecessors. unsigned LoopMDKind = BB->getContext().getMDKindID("llvm.loop"); Instruction *TI = BB->getTerminator(); - if (TI) + if (TI) { if (MDNode *LoopMD = TI->getMetadata(LoopMDKind)) for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { BasicBlock *Pred = *PI; Pred->getTerminator()->setMetadata(LoopMDKind, LoopMD); } + // Replace the terminator instruction with unreachable to ensure the CFG is + // consistent. This is necessary for dominance to be correctly calculated. + new UnreachableInst(BB->getContext(), TI); + TI->eraseFromParent(); + } // Everything that jumped to BB now goes to Succ. BB->replaceAllUsesWith(Succ); if (!Succ->hasName()) Succ->takeName(BB); + + if (DT) { + Updates.push_back({DominatorTree::Delete, BB, Succ}); + DT->applyUpdates(Updates); + } + BB->eraseFromParent(); // Delete the old basic block. return true; } @@ -1399,13 +1488,19 @@ unsigned llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) { } unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap, - bool PreserveLCSSA) { + bool PreserveLCSSA, DominatorTree *DT) { BasicBlock *BB = I->getParent(); + std::vector<DominatorTree::UpdateType> Updates; // Loop over all of the successors, removing BB's entry from any PHI // nodes. - for (BasicBlock *Successor : successors(BB)) + for (BasicBlock *Successor : successors(BB)) { Successor->removePredecessor(BB, PreserveLCSSA); - + if (DT && BB != Successor) { + DominatorTree::UpdateType UT = {DominatorTree::Delete, BB, Successor}; + if (std::find(Updates.begin(), Updates.end(), UT) == Updates.end()) + Updates.push_back(UT); + } + } // Insert a call to llvm.trap right before this. This turns the undefined // behavior into a hard fail instead of falling through into random code. if (UseLLVMTrap) { @@ -1425,11 +1520,13 @@ unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap, BB->getInstList().erase(BBI++); ++NumInstrsRemoved; } + if (DT && !Updates.empty()) + DT->applyUpdates(Updates); return NumInstrsRemoved; } /// changeToCall - Convert the specified invoke into a normal call. -static void changeToCall(InvokeInst *II) { +static void changeToCall(InvokeInst *II, DominatorTree *DT = nullptr) { SmallVector<Value*, 8> Args(II->arg_begin(), II->arg_end()); SmallVector<OperandBundleDef, 1> OpBundles; II->getOperandBundlesAsDefs(OpBundles); @@ -1442,11 +1539,16 @@ static void changeToCall(InvokeInst *II) { II->replaceAllUsesWith(NewCall); // Follow the call by a branch to the normal destination. - BranchInst::Create(II->getNormalDest(), II); + BasicBlock *NormalDestBB = II->getNormalDest(); + BranchInst::Create(NormalDestBB, II); // Update PHI nodes in the unwind destination - II->getUnwindDest()->removePredecessor(II->getParent()); + BasicBlock *BB = II->getParent(); + BasicBlock *UnwindDestBB = II->getUnwindDest(); + UnwindDestBB->removePredecessor(BB); II->eraseFromParent(); + if (DT && BB != UnwindDestBB && NormalDestBB != UnwindDestBB) + DT->deleteEdge(BB, UnwindDestBB); } BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI, @@ -1487,7 +1589,8 @@ BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI, } static bool markAliveBlocks(Function &F, - SmallPtrSetImpl<BasicBlock*> &Reachable) { + SmallPtrSetImpl<BasicBlock *> &Reachable, + DominatorTree *DT = nullptr) { SmallVector<BasicBlock*, 128> Worklist; BasicBlock *BB = &F.front(); @@ -1508,7 +1611,7 @@ static bool markAliveBlocks(Function &F, if (II->getIntrinsicID() == Intrinsic::assume) { if (match(II->getArgOperand(0), m_CombineOr(m_Zero(), m_Undef()))) { // Don't insert a call to llvm.trap right before the unreachable. - changeToUnreachable(II, false); + changeToUnreachable(II, false, false, DT); Changed = true; break; } @@ -1525,7 +1628,8 @@ static bool markAliveBlocks(Function &F, // still be useful for widening. if (match(II->getArgOperand(0), m_Zero())) if (!isa<UnreachableInst>(II->getNextNode())) { - changeToUnreachable(II->getNextNode(), /*UseLLVMTrap=*/ false); + changeToUnreachable(II->getNextNode(), /*UseLLVMTrap=*/false, + false, DT); Changed = true; break; } @@ -1535,7 +1639,7 @@ static bool markAliveBlocks(Function &F, if (auto *CI = dyn_cast<CallInst>(&I)) { Value *Callee = CI->getCalledValue(); if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee)) { - changeToUnreachable(CI, /*UseLLVMTrap=*/false); + changeToUnreachable(CI, /*UseLLVMTrap=*/false, false, DT); Changed = true; break; } @@ -1545,7 +1649,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); + changeToUnreachable(CI->getNextNode(), false, false, DT); Changed = true; } break; @@ -1564,7 +1668,7 @@ static bool markAliveBlocks(Function &F, if (isa<UndefValue>(Ptr) || (isa<ConstantPointerNull>(Ptr) && SI->getPointerAddressSpace() == 0)) { - changeToUnreachable(SI, true); + changeToUnreachable(SI, true, false, DT); Changed = true; break; } @@ -1576,16 +1680,19 @@ static bool markAliveBlocks(Function &F, // Turn invokes that call 'nounwind' functions into ordinary calls. Value *Callee = II->getCalledValue(); if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee)) { - changeToUnreachable(II, true); + changeToUnreachable(II, true, false, DT); Changed = true; } else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(&F)) { if (II->use_empty() && II->onlyReadsMemory()) { // jump to the normal destination branch. + BasicBlock *UnwindDestBB = II->getUnwindDest(); BranchInst::Create(II->getNormalDest(), II); - II->getUnwindDest()->removePredecessor(II->getParent()); + UnwindDestBB->removePredecessor(II->getParent()); II->eraseFromParent(); + if (DT && BB != UnwindDestBB) + DT->deleteEdge(BB, UnwindDestBB); } else - changeToCall(II); + changeToCall(II, DT); Changed = true; } } else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Terminator)) { @@ -1628,7 +1735,7 @@ static bool markAliveBlocks(Function &F, } } - Changed |= ConstantFoldTerminator(BB, true); + Changed |= ConstantFoldTerminator(BB, true, nullptr, DT); for (BasicBlock *Successor : successors(BB)) if (Reachable.insert(Successor).second) Worklist.push_back(Successor); @@ -1636,11 +1743,11 @@ static bool markAliveBlocks(Function &F, return Changed; } -void llvm::removeUnwindEdge(BasicBlock *BB) { +void llvm::removeUnwindEdge(BasicBlock *BB, DominatorTree *DT) { TerminatorInst *TI = BB->getTerminator(); if (auto *II = dyn_cast<InvokeInst>(TI)) { - changeToCall(II); + changeToCall(II, DT); return; } @@ -1668,15 +1775,19 @@ void llvm::removeUnwindEdge(BasicBlock *BB) { UnwindDest->removePredecessor(BB); TI->replaceAllUsesWith(NewTI); TI->eraseFromParent(); + if (DT && BB != UnwindDest) + DT->deleteEdge(BB, UnwindDest); } /// removeUnreachableBlocks - Remove blocks that are not reachable, even /// if they are in a dead cycle. Return true if a change was made, false /// otherwise. If `LVI` is passed, this function preserves LazyValueInfo /// after modifying the CFG. -bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI) { +bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI, + DominatorTree *DT) { SmallPtrSet<BasicBlock*, 16> Reachable; - bool Changed = markAliveBlocks(F, Reachable); + bool Changed = markAliveBlocks(F, Reachable, DT); + std::vector<DominatorTree::UpdateType> Updates; // If there are unreachable blocks in the CFG... if (Reachable.size() == F.size()) @@ -1685,6 +1796,8 @@ bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI) { assert(Reachable.size() < F.size()); NumRemoved += F.size()-Reachable.size(); + SmallPtrSet<TerminatorInst *, 4> TIRemoved; + // Loop over all of the basic blocks that are not reachable, dropping all of // their internal references... for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB) { @@ -1692,13 +1805,35 @@ bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI) { continue; for (BasicBlock *Successor : successors(&*BB)) - if (Reachable.count(Successor)) + if (Reachable.count(Successor)) { Successor->removePredecessor(&*BB); + if (DT && &*BB != Successor) { + DominatorTree::UpdateType UT = {DominatorTree::Delete, &*BB, + Successor}; + if (std::find(Updates.begin(), Updates.end(), UT) == Updates.end()) + Updates.push_back(UT); + } + } + if (LVI) LVI->eraseBlock(&*BB); + + TerminatorInst *TI = BB->getTerminator(); + TIRemoved.insert(TI); + new UnreachableInst(BB->getContext(), TI); + BB->dropAllReferences(); } + // Remove all the terminator instructions after dropping all references. This + // keeps the state of the CFG consistent and prevents asserts from circular + // use counts in groups of unreachable basic blocks. + for (TerminatorInst *TI : TIRemoved) + TI->eraseFromParent(); + + if (DT && !Updates.empty()) + DT->applyUpdates(Updates); + for (Function::iterator I = ++F.begin(); I != F.end();) if (!Reachable.count(&*I)) I = F.getBasicBlockList().erase(I); |